From 224fe4209fcdae1e35208653974949c5edda04a1 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 20 Aug 2024 09:52:21 -0600 Subject: [PATCH 01/32] pointing frame code --- imap_processing/pointing_frame_handler.py | 237 ++++++++++++++++++ .../tests/pointing_frame/__init__.py | 0 .../test_pointing_frame_handler.py | 136 ++++++++++ 3 files changed, 373 insertions(+) create mode 100644 imap_processing/pointing_frame_handler.py create mode 100644 imap_processing/tests/pointing_frame/__init__.py create mode 100644 imap_processing/tests/pointing_frame/test_pointing_frame_handler.py diff --git a/imap_processing/pointing_frame_handler.py b/imap_processing/pointing_frame_handler.py new file mode 100644 index 000000000..9ff869458 --- /dev/null +++ b/imap_processing/pointing_frame_handler.py @@ -0,0 +1,237 @@ +"""Generate Pointing Frame. + +Notes +----- +Kernels that are required to run this code: +1. imap_science_0001.tf - pointing frame kernel +2. imap_sclk_0000.tsc - spacecraft clock kernel +3. imap_wkcp.tf - spacecraft frame kernel +4. de430.bsp - standard SPICE planetary ephemeris kernel +5. naif0012.tls - standard NAIF leapsecond kernel +6. imap_spin.bc - test attitude kernel available at: +https://lasp.colorado.edu/galaxy/display/IMAP/Data +These need to be placed in tests/pointing_frame/test_data. + +References +---------- +https://spiceypy.readthedocs.io/en/main/documentation.html. +""" + +import logging +import os +from pathlib import Path + +import numpy as np +import spiceypy as spice + +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) + +# TODO : Add multiple pointings to the pointing frame. + + +def get_coverage(ck_kernel): + """Create the pointing frame. + + Parameters + ---------- + ck_kernel : str + Path of ck_kernel used to create the pointing frame. + + Returns + ------- + et_start : float + Start time of ck_kernel. + et_end : float + End time of ck_kernel. + et_times : numpy.ndarray + Array of times between et_start and et_end. + """ + # Each spin is 15 seconds. We want 10 quaternions per spin. + # duration / # samples (nominally 15/10 = 1.5 seconds) + step = 1.5 + + # Get the spacecraft ID. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool + id_imap_spacecraft = spice.gipool("FRAME_IMAP_SPACECRAFT", 0, 1) + + # TODO: Queried pointing start and stop times here. + + # Get the coverage window + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckcov + cover = spice.ckcov(ck_kernel, int(id_imap_spacecraft), True, "SEGMENT", 0, "TDB") + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.wnfetd + et_start, et_end = spice.wnfetd(cover, 0) + et_times = np.arange(et_start, et_end, step) + + return et_start, et_end, et_times + + +def average_quaternions(et_times): + """Average the quaternions. + + Parameters + ---------- + et_times : numpy.ndarray + Array of times between et_start and et_end. + + Returns + ------- + q_avg : np.array + Average quaternion. + z_eclip_time : list + Z-axis of the ECLIPJ2000 frame. Used for plotting. + """ + z_eclip_time = [] + aggregate = np.zeros((4, 4)) + + for tdb in et_times: + # Rotation matrix from IMAP spacecraft frame to ECLIPJ2000. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.pxform + body_rots = spice.pxform("IMAP_SPACECRAFT", "ECLIPJ2000", tdb) + # Convert rotation matrix to quaternion. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.m2q + body_quat = spice.m2q(body_rots) + # z-axis of the ECLIPJ2000 frame. + z_eclip_time.append(body_rots[:, 2]) + + # Standardize the quaternion so that they may be compared. + if body_quat[0] < 0: + body_quat = -body_quat + + # Aggregate quaternions into a single matrix. + aggregate += np.outer(body_quat, body_quat) + + # Reference: Claus Gramkow "On Averaging Rotations" + # Link: https://link.springer.com/content/pdf/10.1023/A:1011129215388.pdf + aggregate /= len(et_times) + + # Compute eigen values and vectors of the matrix A + # Eigenvalues tell you how much "influence" each + # direction (eigenvector) has. + # The largest eigenvalue corresponds to the direction + # that has the most influence. + # The eigenvector corresponding to the largest + # eigenvalue points in the direction that has the most + # combined rotation influence. + eigvals, eigvecs = np.linalg.eig(aggregate) + # q0: The scalar part of the quaternion. + # q1, q2, q3: The vector part of the quaternion. + q_avg = eigvecs[:, np.argmax(eigvals)] + + return q_avg, z_eclip_time + + +def create_rotation_matrix(et_times): + """Create a rotation matrix. + + Parameters + ---------- + et_times : numpy.ndarray + Array of times between et_start and et_end. + + Returns + ------- + rotation_matrix : np.array + Rotation matrix. + z_avg : np.array + Inertial z axis. Used for plotting. + """ + # Averaged quaternions. + q_avg, _ = average_quaternions(et_times) + + # Converts the averaged quaternion (q_avg) into a rotation matrix + # and get inertial z axis. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.q2m + z_avg = spice.q2m(list(q_avg))[:, 2] + # y_avg is perpendicular to both z_avg and the standard Z-axis. + y_avg = np.cross(z_avg, [0, 0, 1]) + # x_avg is perpendicular to y_avg and z_avg. + x_avg = np.cross(y_avg, z_avg) + + # Construct the rotation matrix from x_avg, y_avg, z_avg + rotation_matrix = np.array([x_avg, y_avg, z_avg]) + + return rotation_matrix, z_avg + + +def create_pointing_frame(): + """Create the pointing frame. + + Returns + ------- + path_to_pointing_frame : str + Path to dps frame. + """ + # Mount path to EFS. + mount_path = Path(os.getenv("EFS_MOUNT_PATH")) + + # TODO: this part will change with ensure_spice decorator. + kernels = [str(file) for file in mount_path.iterdir()] + ck_kernel = [str(file) for file in mount_path.iterdir() if file.suffix == ".bc"] + + # Furnish the kernels. + with spice.KernelPool(kernels): + # Get timerange for the pointing frame kernel. + et_start, et_end, et_times = get_coverage(str(ck_kernel[0])) + # Create a rotation matrix + rotation_matrix, _ = create_rotation_matrix(et_times) + + # Convert the rotation matrix to a quaternion. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.m2q + q_avg = spice.m2q(rotation_matrix) + + # TODO: come up with naming convention. + path_to_pointing_frame = mount_path / "imap_dps.bc" + + # Open a new CK file, returning the handle of the opened file. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckopn + handle = spice.ckopn(str(path_to_pointing_frame), "CK", 0) + # Get the SCLK ID. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool + id_imap_sclk = spice.gipool("CK_-43000_SCLK", 0, 1) + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.sce2c + # Convert start and end times to SCLK. + sclk_begtim = spice.sce2c(int(id_imap_sclk), et_start) + sclk_endtim = spice.sce2c(int(id_imap_sclk), et_end) + + # Get the pointing frame ID. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool + id_imap_dps = spice.gipool("FRAME_IMAP_DPS", 0, 1) + + # Create the pointing frame kernel. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckw02 + spice.ckw02( + # Handle of an open CK file. + handle, + # Start time of the segment. + sclk_begtim, + # End time of the segment. + sclk_endtim, + # Pointing frame ID. + int(id_imap_dps), + # Reference frame. + "ECLIPJ2000", # Reference frame + # Identifier. + "IMAP_DPS", + # Number of pointing intervals. + 1, + # Start times of individual pointing records within segment. + # Since there is only a single record this is equal to sclk_begtim. + np.array([sclk_begtim]), + # End times of individual pointing records within segment. + # Since there is only a single record this is equal to sclk_endtim. + np.array([sclk_endtim]), # Single stop time + # Average quaternion. + q_avg, + # 0.0 Angular rotation terms. + np.array([0.0, 0.0, 0.0]), + # Rates (seconds per tick) at which the quaternion and + # angular velocity change. + np.array([1.0]), + ) + + # Close CK file. + spice.ckcls(handle) + + return path_to_pointing_frame diff --git a/imap_processing/tests/pointing_frame/__init__.py b/imap_processing/tests/pointing_frame/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py b/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py new file mode 100644 index 000000000..34c875ce3 --- /dev/null +++ b/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py @@ -0,0 +1,136 @@ +"""Tests Pointing Frame Generation.""" + +import shutil +import sys +from pathlib import Path + +import matplotlib.pyplot as plt +import numpy as np +import pytest +import spiceypy as spice + +from imap_processing.pointing_frame_handler import ( + average_quaternions, + create_pointing_frame, + create_rotation_matrix, + get_coverage, +) + + +@pytest.fixture() +def kernel_path(tmp_path): + """Create path to kernels.""" + + test_dir = ( + Path(sys.modules[__name__.split(".")[0]].__file__).parent + / "tests" + / "pointing_frame" + / "test_data" + ) + + kernels = [ + "de430.bsp", + "naif0012.tls", + "imap_science_0001.tf", + "imap_sclk_0000.tsc", + "imap_wkcp.tf", + "imap_spin.bc", + ] + + for file in test_dir.iterdir(): + if file.name in kernels: + shutil.copy(file, tmp_path / file.name) + + return tmp_path + + +@pytest.fixture() +def create_kernel_list(kernel_path): + """Create kernel lists.""" + kernels = [str(file) for file in kernel_path.iterdir()] + ck_kernel = [ + str(file) for file in kernel_path.iterdir() if file.name == "imap_spin.bc" + ] + + return kernels, ck_kernel + + +# @pytest.mark.xfail(reason="Will fail unless imap_spin.bc is in /test-data/spice/.") +def test_get_coverage(create_kernel_list): + """Tests get_coverage function.""" + kernels, ck_kernel = create_kernel_list + + with spice.KernelPool(kernels): + et_start, et_end, et_times = get_coverage(str(ck_kernel[0])) + + assert et_start == 802008069.184905 + assert et_end == 802094467.184905 + + +# @pytest.mark.xfail(reason="Will fail unless imap_spin.bc is in /test-data/spice/.") +def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): + """Tests create_pointing_frame function.""" + monkeypatch.setenv("EFS_MOUNT_PATH", str(kernel_path)) + _, ck_kernel = create_kernel_list + create_pointing_frame() + + # After imap_dps.bc has been created. + kernels = [str(file) for file in kernel_path.iterdir()] + + with spice.KernelPool(kernels): + et_start, et_end, et_times = get_coverage(str(ck_kernel[0])) + + rotation_matrix_1 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 100) + rotation_matrix_2 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 1000) + + # All the rotation matrices should be the same. + assert np.array_equal(rotation_matrix_1, rotation_matrix_2) + + # Nick Dutton's MATLAB code result + rotation_matrix_expected = np.array( + [[0.0000, 0.0000, 1.0000], [0.9104, -0.4136, 0.0000], [0.4136, 0.9104, 0.0000]] + ) + np.testing.assert_allclose(rotation_matrix_1, rotation_matrix_expected, atol=1e-4) + + +# @pytest.mark.xfail(reason="Will fail unless imap_spin.bc is in /test-data/spice/.") +def test_z_axis(create_kernel_list): + """Tests Inertial z axis and provides visualization.""" + kernels, ck_kernel = create_kernel_list + + with spice.KernelPool(kernels): + et_start, et_end, et_times = get_coverage(str(ck_kernel[0])) + + # Converts rectangular coordinates to spherical coordinates. + q_avg, z_eclip_time = average_quaternions(et_times) + z_avg_expected = spice.q2m(list(q_avg))[:, 2] + _, z_avg = create_rotation_matrix(et_times) + + assert np.array_equal(z_avg, z_avg_expected) + + # Create visualization + declination_list = [] + for time in z_eclip_time: + _, _, declination = spice.recrad(list(time)) + declination_list.append(declination) + + # Average declination. + _, _, avg_declination = spice.recrad(list(z_avg)) + + # Plotting for visualization + plt.figure() + plt.plot( + et_times, np.array(declination_list) * 180 / np.pi, "-b", label="Declination" + ) + plt.plot( + et_times, + np.full(len(et_times), avg_declination * 180 / np.pi), + "-r", + linewidth=2, + label="mean z-axis for pointing frame", + ) + plt.xlabel("Ephemeris Time") + plt.ylabel("Spacecraft Spin Axis Declination") + plt.ticklabel_format(useOffset=False) + plt.legend() + plt.show() From c27926b86727e6c234fd2e2d8a48de05efb905f6 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 20 Aug 2024 10:07:18 -0600 Subject: [PATCH 02/32] pointing frame code format --- imap_processing/pointing_frame_handler.py | 37 +++++++++++++---------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/imap_processing/pointing_frame_handler.py b/imap_processing/pointing_frame_handler.py index 9ff869458..c10e76653 100644 --- a/imap_processing/pointing_frame_handler.py +++ b/imap_processing/pointing_frame_handler.py @@ -1,4 +1,5 @@ -"""Generate Pointing Frame. +""" +Generate Pointing Frame. Notes ----- @@ -9,7 +10,7 @@ 4. de430.bsp - standard SPICE planetary ephemeris kernel 5. naif0012.tls - standard NAIF leapsecond kernel 6. imap_spin.bc - test attitude kernel available at: -https://lasp.colorado.edu/galaxy/display/IMAP/Data + https://lasp.colorado.edu/galaxy/display/IMAP/Data These need to be placed in tests/pointing_frame/test_data. References @@ -30,8 +31,9 @@ # TODO : Add multiple pointings to the pointing frame. -def get_coverage(ck_kernel): - """Create the pointing frame. +def get_coverage(ck_kernel: str) -> tuple[float, float, np.ndarray]: + """ + Create the pointing frame. Parameters ---------- @@ -67,8 +69,9 @@ def get_coverage(ck_kernel): return et_start, et_end, et_times -def average_quaternions(et_times): - """Average the quaternions. +def average_quaternions(et_times: np.ndarray) -> tuple[np.ndarray, list[np.ndarray]]: + """ + Average the quaternions. Parameters ---------- @@ -77,7 +80,7 @@ def average_quaternions(et_times): Returns ------- - q_avg : np.array + q_avg : np.ndarray Average quaternion. z_eclip_time : list Z-axis of the ECLIPJ2000 frame. Used for plotting. @@ -102,7 +105,7 @@ def average_quaternions(et_times): # Aggregate quaternions into a single matrix. aggregate += np.outer(body_quat, body_quat) - # Reference: Claus Gramkow "On Averaging Rotations" + # Reference: "On Averaging Rotations" # Link: https://link.springer.com/content/pdf/10.1023/A:1011129215388.pdf aggregate /= len(et_times) @@ -122,8 +125,9 @@ def average_quaternions(et_times): return q_avg, z_eclip_time -def create_rotation_matrix(et_times): - """Create a rotation matrix. +def create_rotation_matrix(et_times: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """ + Create a rotation matrix. Parameters ---------- @@ -132,9 +136,9 @@ def create_rotation_matrix(et_times): Returns ------- - rotation_matrix : np.array + rotation_matrix : np.ndarray Rotation matrix. - z_avg : np.array + z_avg : np.ndarray Inertial z axis. Used for plotting. """ # Averaged quaternions. @@ -155,16 +159,17 @@ def create_rotation_matrix(et_times): return rotation_matrix, z_avg -def create_pointing_frame(): - """Create the pointing frame. +def create_pointing_frame() -> Path: + """ + Create the pointing frame. Returns ------- - path_to_pointing_frame : str + path_to_pointing_frame : Path Path to dps frame. """ # Mount path to EFS. - mount_path = Path(os.getenv("EFS_MOUNT_PATH")) + mount_path = Path(os.getenv("EFS_MOUNT_PATH", "")) # TODO: this part will change with ensure_spice decorator. kernels = [str(file) for file in mount_path.iterdir()] From 47ae48072950361e1b031d3d03a38c6016b65d24 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 20 Aug 2024 10:11:07 -0600 Subject: [PATCH 03/32] add data --- .../test_data/imap_science_0001.tf | 171 ++ .../test_data/imap_sclk_0000.tsc | 147 ++ .../pointing_frame/test_data/imap_wkcp.tf | 1806 +++++++++++++++++ 3 files changed, 2124 insertions(+) create mode 100644 imap_processing/tests/pointing_frame/test_data/imap_science_0001.tf create mode 100644 imap_processing/tests/pointing_frame/test_data/imap_sclk_0000.tsc create mode 100644 imap_processing/tests/pointing_frame/test_data/imap_wkcp.tf diff --git a/imap_processing/tests/pointing_frame/test_data/imap_science_0001.tf b/imap_processing/tests/pointing_frame/test_data/imap_science_0001.tf new file mode 100644 index 000000000..c7caa49ac --- /dev/null +++ b/imap_processing/tests/pointing_frame/test_data/imap_science_0001.tf @@ -0,0 +1,171 @@ +KPL/FK + +Interstellar Mapping and Acceleration Probe Dynamic Frames Kernel +======================================================================== + + This kernel contains SPICE frame definitions to support the IMAP mission. + + To be consistent with conventions prior to the mission name change + from Solar Probe Plus (SPP) to Parker Solar Probe (PSP) in 2017, frame + names and other text IDs are prefixed with the legacy acronym, SPP. + +Version and Date +--------------------------------------------------------------- + + The TEXT_KERNEL_ID stores version information of loaded project text + kernels. Each entry associated with the keyword is a string that + consists of four parts: the kernel name, version, entry date, and type. + + SPP Dynamic Frame Kernel Version: + + \begindata + + TEXT_KERNEL_ID = 'IMAP_DYNAMIC_FRAMES V1.0.0 2024-XXXX-NN FK' + + \begintext + + + Version 1.0.0 -- April 10, 2024 -- Nick Dutton (JHU/APL) + + +References +--------------------------------------------------------------- + + 1. NAIF SPICE `Kernel Pool Required Reading' + + 2. NAIF SPICE `Frames Required Reading' + + 3. Email from Scott Turner, received May 2, 2018, containing + attachment InstrumentFrames.pptx, by Martha Kusterer dated + Sept. 19, 2017 + + 4. msgr_dyn_v600.tf, in Planetary Data System (PDS) + data set MESS-E/V/H-SPICE-6-V1.0 + + 5. stereo_rtn.tf, at + ftp://sohoftp.nascom.nasa.gov/solarsoft/stereo/gen/data/spice + + 6. heliospheric.tf, at + ftp://sohoftp.nascom.nasa.gov/solarsoft/stereo/gen/data/spice/gen + + 7. Email from Scott Turner received May 11, 2018 containing notes + taken from the science team meeting on the same date. + + 8. Snodgrass, H.B., Ulrich, R.K., 1990, Rotation of Doppler features + in the solar photosphere. Astrophys. J. 351, 309. doi:10.1086/168467 + + +Contact Information +--------------------------------------------------------------- + + Direct questions, comments, or concerns about the contents of this + kernel to: + + Scott Turner, JHUAPL, (443)778-1693, Scott.Turner@jhuapl.edu + + or + + Lillian Nguyen, JHUAPL (443)778-5477, Lillian.Nguyen@jhuapl.edu + + or + + Douglas Rodgers, JHUAPL (443)778-4228, Douglas.Rodgers@jhuapl.edu + + +Implementation Notes +--------------------------------------------------------------- + + This file is used by the SPICE system as follows: programs that make use + of this frame kernel must `load' the kernel normally during program + initialization. Loading the kernel associates the data items with + their names in a data structure called the `kernel pool'. The SPICELIB + routine FURNSH loads a kernel into the pool as shown below: + + FORTRAN: (SPICELIB) + + CALL FURNSH ( frame_kernel_name ) + + C: (CSPICE) + + furnsh_c ( frame_kernel_name ); + + IDL: (ICY) + + cspice_furnsh, frame_kernel_name + + MATLAB: (MICE) + + cspice_furnsh ( frame_kernel_name ) + + This file was created and may be updated with a text editor or word + processor. + + +IMAP Dynamic Frames +--------------------------------------------------------------- + + This frame kernel defines a series of dynamic frames listed in [3] + that support Parker Solar Probe data reduction and analysis. All + of the frame names defined by this kernel are prefixed with 'SPP_' + (the legacy mission name acronym as described in the leading paragraph + of this file) to avoid conflict with alternative definitions not + specific to the project. Further, the project-specific ID codes + -96900 to -96999 have been set aside to support these dynamic frames. + + The following dynamic frames are defined in this kernel file: + + Frame Name Relative To Type NAIF ID + ====================== =================== ======= ======= + + Earth Based Frames: + ------------------ + EARTH_FIXED IAU_EARTH FIXED + IMAP_RTN J2000 DYNAMIC -96900 + SPP_GSE J2000 DYNAMIC -96901 + + Mercury Based Frames: + ------------------ + SPP_MSO J2000 DYNAMIC -96903 + + Venus Based Frames: + ------------------ + SPP_VSO J2000 DYNAMIC -96904 + + Sun Based Frames: + ------------------ + SPP_HG J2000 DYNAMIC -96910 + SPP_HCI J2000 DYNAMIC -96911 + SPP_HEE J2000 DYNAMIC -96912 + SPP_HEEQ J2000 DYNAMIC -96913 + SPP_RTN J2000 DYNAMIC -96914 + SPP_HERTN J2000 DYNAMIC -96915 + SPP_HGI J2000 DYNAMIC -96916 + SPP_HGDOPP J2000 DYNAMIC -96917 + SPP_HGMAG J2000 DYNAMIC -96918 + SPP_HGSPEC J2000 DYNAMIC -96919 + + + + \begindata + + NAIF_BODY_NAME += ( 'IMAP_DPS' ) + NAIF_BODY_CODE += ( -43901 ) + + + + \begintext + +DPS Frame + +\begindata + + FRAME_IMAP_DPS = -43901 + FRAME_-43901_NAME = 'IMAP_DPS' + FRAME_-43901_CLASS = 3 + FRAME_-43901_CLASS_ID = -43901 + FRAME_-43901_CENTER = -43 + CK_-43901_SCLK = -43 + + \begintext + +END OF FILE diff --git a/imap_processing/tests/pointing_frame/test_data/imap_sclk_0000.tsc b/imap_processing/tests/pointing_frame/test_data/imap_sclk_0000.tsc new file mode 100644 index 000000000..c52514a3c --- /dev/null +++ b/imap_processing/tests/pointing_frame/test_data/imap_sclk_0000.tsc @@ -0,0 +1,147 @@ +\begintext + +FILENAME = "imap_0000.tsc" +CREATION_DATE = "2-October-2018" + + +IMAP Spacecraft Clock Kernel (SCLK) +=========================================================================== + + This file is a SPICE spacecraft clock (SCLK) kernel containing + information required for time conversions involving the on-board + IMAP spacecraft clock. + +Version +-------------------------------------------------------- + + IMAP SCLK Kernel Version: + + IMAP Version 0.0 - April 12, 2023 -- Ian W. Murphy + The initial IMAP spice kernel. + This file was created by using DART initial kernel and + modifying the spacecraft ID. + + +Usage +-------------------------------------------------------- + + This file is used by the SPICE system as follows: programs that + make use of this SCLK kernel must 'load' the kernel, normally + during program initialization. Loading the kernel associates + the data items with their names in a data structure called the + 'kernel pool'. The SPICELIB routine FURNSH loads text kernel + files, such as this one, into the pool as shown below: + + FORTRAN: + + CALL FURNSH ( SCLK_kernel_name ) + + C: + + furnsh_c ( SCLK_kernel_name ); + + Once loaded, the SCLK time conversion routines will be able to + access the necessary data located in this kernel for their + designed purposes. + +References +-------------------------------------------------------- + + 1. "SCLK Required Reading" + +Inquiries +-------------------------------------------------------- + + If you have any questions regarding this file or its usage, + contact: + + Scott Turner + (443)778-1693 + Scott.Turner@jhuapl.edu + +Kernel Data +-------------------------------------------------------- + + The first block of keyword equals value assignments define the + type, parallel time system, and format of the spacecraft clock. + These fields are invariant from SCLK kernel update to SCLK + kernel update. + + The IMAP spacecraft clock is represented by the SPICE + type 1 SCLK kernel. It uses TDT, Terrestrial Dynamical Time, + as its parallel time system. + +\begindata + +SCLK_KERNEL_ID = ( @2009-07-09T12:20:32 ) +SCLK_DATA_TYPE_43 = ( 1 ) +SCLK_DATA_TYPE_43000 = ( 1 ) +SCLK01_TIME_SYSTEM_43 = ( 2 ) + +\begintext + + In a particular partition of the IMAP spacecraft clock, + the clock read-out consists of two separate stages: + + 1/18424652:24251 + + The first stage, a 32 bit field, represents the spacecraft + clock seconds count. The second, a 16 bit field, represents + counts of 20 microsecond increments of the spacecraft clock. + + The following keywords and their values establish this structure: + +\begindata + +SCLK01_N_FIELDS_43 = ( 2 ) +SCLK01_MODULI_43 = ( 4294967296 50000 ) +SCLK01_OFFSETS_43 = ( 0 0 ) +SCLK01_OUTPUT_DELIM_43 = ( 2 ) + + +\begintext + + This concludes the invariant portion of the SCLK kernel data. The + remaining sections of the kernel may require updates as the clock + correlation coefficients evolve in time. The first section below + establishes the clock partitions. The data in this section consists + of two parallel arrays, which denote the start and end values in + ticks of each partition of the spacecraft clock. + + SPICE utilizes these two arrays to map from spacecraft clock ticks, + determined with the usual modulo arithmetic, to encoded SCLK--the + internal, monotonically increasing sequence used to tag various + data sources with spacecraft clock. + +\begindata + +SCLK_PARTITION_START_43 = ( 0.00000000000000e+00 ) + +SCLK_PARTITION_END_43 = ( 2.14748364799999e+14 ) + +\begintext + + The remaining section of the SCLK kernel defines the clock correlation + coefficients. Each line contains a 'coefficient triple': + + Encoded SCLK at which Rate is introduced. + Corresponding TDT Epoch at which Rate is introduced. + Rate in TDT (seconds) / most significant clock count (~seconds). + + SPICE uses linear extrapolation to convert between the parallel time + system and encoded SCLK. The triples are stored in the array defined + below. + + The first time triplet below was entered manually and represents the + approximate time (in TDT) at which MET = zero. The current plan for + IMAP is that the given epoch will be used for both Observatory I&T + and launch. Note that the conversion from UTC to TDT used 34 leap + seconds. + +\begindata + +SCLK01_COEFFICIENTS_43 = ( + + 0 @01-JAN-2010-00:01:06.184000 1.00000000000 + +) diff --git a/imap_processing/tests/pointing_frame/test_data/imap_wkcp.tf b/imap_processing/tests/pointing_frame/test_data/imap_wkcp.tf new file mode 100644 index 000000000..10ceb4ddf --- /dev/null +++ b/imap_processing/tests/pointing_frame/test_data/imap_wkcp.tf @@ -0,0 +1,1806 @@ +KPL/FK + +Interstellar Mapping and Acceleration Probe Frames Kernel +======================================================================== + + This frames kernel contains the current set of coordinate frame + definitions for the Interstellar Mapping and Acceleration Probe + (IMAP) spacecraft, structures, and science instruments. + + This kernel also contains NAIF ID/name mapping for the IMAP + instruments. + + +Version and Date +======================================================================== + + The TEXT_KERNEL_ID stores version information of loaded project text + kernels. Each entry associated with the keyword is a string that + consists of four parts: the kernel name, version, entry date, and + type. For example, the frames kernel might have an entry as follows: + + + TEXT_KERNEL_ID += 'IMAP_FRAMES V1.0.0 2024-XXXX-NN FK' + | | | | + | | | | + KERNEL NAME <-------+ | | | + | | V + VERSION <------+ | KERNEL TYPE + | + V + ENTRY DATE + + + Interstellar Mapping and Acceleration Probe Frames Kernel Version: + + \begindata + + TEXT_KERNEL_ID += 'IMAP_FRAMES V1.0.0 2024-XXXX-NN FK' + + \begintext + + Version 1.0.0 -- XXXX NN, 2024 -- Douglas Rodgers + Lillian Nguyen + Nicholas Dutton + + Initial complete release. Frame/Body codes for thrusters redefined + + Version 0.0.1 -- July 9, 2021 -- Ian Wick Murphy + + Modifying dart_008.tf to add basic IMAP frame components. This + includes IMAP, IMAP_THRUSTER, and CK/SCLK IDs. Also adding a place + holder for the IMAP-Lo instrument with the ID -43001 and IMAP_LO + name. Future work includes adding more detailed instrument frames, + and reaching out to mechanical for an "official" IMAP_SPACECRAFT + frame definition. + + +References +======================================================================== + + 1. "Frames Required Reading" + + 2. "Kernel Pool Required Reading" + + 3. "C-Kernel Required Reading" + + 4. "7516-9067: IMAP Mechanical Interface Control Document", + Johns Hopkins Applied Physics Laboratory + + 5. "7516-9050: IMAP Coordinate Frame & Technical Definitions Doc.", + Johns Hopkins Applied Physics Laboratory + + 6. "7516-0011: IMAP Mechanical Interface Control Drawing", + [EXPORT CONTROLLED], Johns Hopkins Applied Physics Laboratory + + 7. "7523-0008: IMAP ULTRA Mechanical Interface Control Drawing", + [EXPORT CONTROLLED], Johns Hopkins Applied Physics Laboratory + + 8. "058991000: IMAP SWAPI Mechanical Interface Control Drawing", + Princeton University Space Physics + + 9. "GLOWS-CBK-DWG-2020-08-25-019-v4.4: IMAP GLOWS Mechanical + Interface Control Drawing", Centrum Badag Kosmicznych, Polska + Akademia Nauks + + 10. Responses from IMAP instrument teams on their base frame axis + definitions, received in email. + + +Contact Information +======================================================================== + + Douglas Rodgers, JHU/APL, Douglas.Rodgers@jhuapl.edu + + Lillian Nguyen, JHU/APL, Lillian.Nguyen@jhuapl.edu + + Nicholas Dutton, JHU/APL, Nicholas.Dutton@jhuapl.edu + + Ian Wick Murphy, JHU/APL, Ian.Murphy@jhuapl.edu + + +Implementation Notes +======================================================================== + + This file is used by the SPICE system as follows: programs that make + use of this frame kernel must `load' the kernel, normally during + program initialization. Loading the kernel associates the data items + with their names in a data structure called the `kernel pool'. The + SPICELIB routine FURNSH loads a kernel into the pool as shown below: + + FORTRAN: (SPICELIB) + + CALL FURNSH ( frame_kernel_name ) + + C: (CSPICE) + + furnsh_c ( frame_kernel_name ); + + IDL: (ICY) + + cspice_furnsh, frame_kernel_name + + MATLAB: (MICE) + + cspice_furnsh ( frame_kernel_name ) + + This file was created and may be updated with a text editor or word + processor. + + +IMAP NAIF ID Codes -- Definitions +======================================================================== + + This section contains name to NAIF ID mappings for the IMAP mission. + Once the contents of this file are loaded into the KERNEL POOL, these + mappings become available within SPICE, making it possible to use + names instead of ID code in high level SPICE routine calls. + + \begindata + + NAIF_BODY_NAME += ( 'IMAP' ) + NAIF_BODY_CODE += ( -43 ) + + NAIF_BODY_NAME += ( 'IMAP_SPACECRAFT' ) + NAIF_BODY_CODE += ( -43000 ) + + NAIF_BODY_NAME += ( 'IMAP_THRUSTER_A1' ) + NAIF_BODY_CODE += ( -43010 ) + + NAIF_BODY_NAME += ( 'IMAP_THRUSTER_A2' ) + NAIF_BODY_CODE += ( -43011 ) + + NAIF_BODY_NAME += ( 'IMAP_THRUSTER_A3' ) + NAIF_BODY_CODE += ( -43012 ) + + NAIF_BODY_NAME += ( 'IMAP_THRUSTER_A4' ) + NAIF_BODY_CODE += ( -43013 ) + + NAIF_BODY_NAME += ( 'IMAP_THRUSTER_R1' ) + NAIF_BODY_CODE += ( -43020 ) + + NAIF_BODY_NAME += ( 'IMAP_THRUSTER_R2' ) + NAIF_BODY_CODE += ( -43021 ) + + NAIF_BODY_NAME += ( 'IMAP_THRUSTER_R3' ) + NAIF_BODY_CODE += ( -43022 ) + + NAIF_BODY_NAME += ( 'IMAP_THRUSTER_R4' ) + NAIF_BODY_CODE += ( -43023 ) + + NAIF_BODY_NAME += ( 'IMAP_THRUSTER_R5' ) + NAIF_BODY_CODE += ( -43024 ) + + NAIF_BODY_NAME += ( 'IMAP_THRUSTER_R6' ) + NAIF_BODY_CODE += ( -43025 ) + + NAIF_BODY_NAME += ( 'IMAP_THRUSTER_R7' ) + NAIF_BODY_CODE += ( -43026 ) + + NAIF_BODY_NAME += ( 'IMAP_THRUSTER_R8' ) + NAIF_BODY_CODE += ( -43027 ) + + NAIF_BODY_NAME += ( 'IMAP_SUN_SENSOR_PZ' ) + NAIF_BODY_CODE += ( -42030 ) + + NAIF_BODY_NAME += ( 'IMAP_SUN_SENSOR_MZ' ) + NAIF_BODY_CODE += ( -42031 ) + + NAIF_BODY_NAME += ( 'IMAP_STAR_TRACKER_PX' ) + NAIF_BODY_CODE += ( -42040 ) + + NAIF_BODY_NAME += ( 'IMAP_STAR_TRACKER_MX' ) + NAIF_BODY_CODE += ( -42041 ) + + NAIF_BODY_NAME += ( 'IMAP_LOW_GAIN_ANTENNA' ) + NAIF_BODY_CODE += ( -42050 ) + + NAIF_BODY_NAME += ( 'IMAP_MED_GAIN_ANTENNA' ) + NAIF_BODY_CODE += ( -42051 ) + + NAIF_BODY_NAME += ( 'IMAP_NUTATION_DAMPER_01' ) + NAIF_BODY_CODE += ( -42060 ) + + NAIF_BODY_NAME += ( 'IMAP_NUTATION_DAMPER_02' ) + NAIF_BODY_CODE += ( -42061 ) + + NAIF_BODY_NAME += ( 'IMAP_LO_ENA_SENSOR' ) + NAIF_BODY_CODE += ( -42102 ) + + NAIF_BODY_NAME += ( 'IMAP_LO_STAR_SENSOR' ) + NAIF_BODY_CODE += ( -42103 ) + + NAIF_BODY_NAME += ( 'IMAP_HI_45' ) + NAIF_BODY_CODE += ( -42150 ) + + NAIF_BODY_NAME += ( 'IMAP_HI_90' ) + NAIF_BODY_CODE += ( -42175 ) + + NAIF_BODY_NAME += ( 'IMAP_ULTRA_45' ) + NAIF_BODY_CODE += ( -42200 ) + + NAIF_BODY_NAME += ( 'IMAP_ULTRA_90' ) + NAIF_BODY_CODE += ( -42225 ) + + NAIF_BODY_NAME += ( 'IMAP_MAG' ) + NAIF_BODY_CODE += ( -42250 ) + + NAIF_BODY_NAME += ( 'IMAP_SWE_DETECTOR_P63' ) + NAIF_BODY_CODE += ( -42301 ) + + NAIF_BODY_NAME += ( 'IMAP_SWE_DETECTOR_P42' ) + NAIF_BODY_CODE += ( -42302 ) + + NAIF_BODY_NAME += ( 'IMAP_SWE_DETECTOR_P21' ) + NAIF_BODY_CODE += ( -42303 ) + + NAIF_BODY_NAME += ( 'IMAP_SWE_DETECTOR_000' ) + NAIF_BODY_CODE += ( -42304 ) + + NAIF_BODY_NAME += ( 'IMAP_SWE_DETECTOR_M21' ) + NAIF_BODY_CODE += ( -42305 ) + + NAIF_BODY_NAME += ( 'IMAP_SWE_DETECTOR_M42' ) + NAIF_BODY_CODE += ( -42306 ) + + NAIF_BODY_NAME += ( 'IMAP_SWE_DETECTOR_M63' ) + NAIF_BODY_CODE += ( -42307 ) + + NAIF_BODY_NAME += ( 'IMAP_SWAPI_APERTURE_L' ) + NAIF_BODY_CODE += ( -42351 ) + + NAIF_BODY_NAME += ( 'IMAP_SWAPI_APERTURE_R' ) + NAIF_BODY_CODE += ( -42352 ) + + NAIF_BODY_NAME += ( 'IMAP_SWAPI_SUNGLASSES' ) + NAIF_BODY_CODE += ( -42353 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_01' ) + NAIF_BODY_CODE += ( -42401 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_02' ) + NAIF_BODY_CODE += ( -42402 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_03' ) + NAIF_BODY_CODE += ( -42403 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_04' ) + NAIF_BODY_CODE += ( -42404 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_05' ) + NAIF_BODY_CODE += ( -42405 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_06' ) + NAIF_BODY_CODE += ( -42406 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_07' ) + NAIF_BODY_CODE += ( -42407 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_08' ) + NAIF_BODY_CODE += ( -42408 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_09' ) + NAIF_BODY_CODE += ( -42409 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_10' ) + NAIF_BODY_CODE += ( -42410 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_11' ) + NAIF_BODY_CODE += ( -42411 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_12' ) + NAIF_BODY_CODE += ( -42412 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_13' ) + NAIF_BODY_CODE += ( -42413 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_14' ) + NAIF_BODY_CODE += ( -42414 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_15' ) + NAIF_BODY_CODE += ( -42415 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_16' ) + NAIF_BODY_CODE += ( -42416 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_17' ) + NAIF_BODY_CODE += ( -42417 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_18' ) + NAIF_BODY_CODE += ( -42418 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_19' ) + NAIF_BODY_CODE += ( -42419 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_20' ) + NAIF_BODY_CODE += ( -42420 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_21' ) + NAIF_BODY_CODE += ( -42421 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_22' ) + NAIF_BODY_CODE += ( -42422 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_23' ) + NAIF_BODY_CODE += ( -42423 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_LO_APERTURE_24' ) + NAIF_BODY_CODE += ( -42424 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_HI_APERTURE_01' ) + NAIF_BODY_CODE += ( -42425 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_HI_APERTURE_02' ) + NAIF_BODY_CODE += ( -42426 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_HI_APERTURE_03' ) + NAIF_BODY_CODE += ( -42427 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_HI_APERTURE_04' ) + NAIF_BODY_CODE += ( -42428 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_HI_APERTURE_05' ) + NAIF_BODY_CODE += ( -42429 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_HI_APERTURE_06' ) + NAIF_BODY_CODE += ( -42430 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_HI_APERTURE_07' ) + NAIF_BODY_CODE += ( -42431 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_HI_APERTURE_08' ) + NAIF_BODY_CODE += ( -42432 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_HI_APERTURE_09' ) + NAIF_BODY_CODE += ( -42433 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_HI_APERTURE_10' ) + NAIF_BODY_CODE += ( -42434 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_HI_APERTURE_11' ) + NAIF_BODY_CODE += ( -42435 ) + + NAIF_BODY_NAME += ( 'IMAP_CODICE_HI_APERTURE_12' ) + NAIF_BODY_CODE += ( -42436 ) + + NAIF_BODY_NAME += ( 'IMAP_HIT_L1_APERTURE_01' ) + NAIF_BODY_CODE += ( -42501 ) + + NAIF_BODY_NAME += ( 'IMAP_HIT_L1_APERTURE_02' ) + NAIF_BODY_CODE += ( -42502 ) + + NAIF_BODY_NAME += ( 'IMAP_HIT_L1_APERTURE_03' ) + NAIF_BODY_CODE += ( -42503 ) + + NAIF_BODY_NAME += ( 'IMAP_HIT_L1_APERTURE_04' ) + NAIF_BODY_CODE += ( -42504 ) + + NAIF_BODY_NAME += ( 'IMAP_HIT_L1_APERTURE_05' ) + NAIF_BODY_CODE += ( -42505 ) + + NAIF_BODY_NAME += ( 'IMAP_HIT_L1_APERTURE_06' ) + NAIF_BODY_CODE += ( -42506 ) + + NAIF_BODY_NAME += ( 'IMAP_HIT_L1_APERTURE_07' ) + NAIF_BODY_CODE += ( -42507 ) + + NAIF_BODY_NAME += ( 'IMAP_HIT_L1_APERTURE_08' ) + NAIF_BODY_CODE += ( -42508 ) + + NAIF_BODY_NAME += ( 'IMAP_HIT_L1_APERTURE_09' ) + NAIF_BODY_CODE += ( -42509 ) + + NAIF_BODY_NAME += ( 'IMAP_HIT_L1_APERTURE_10' ) + NAIF_BODY_CODE += ( -42510 ) + + NAIF_BODY_NAME += ( 'IMAP_IDEX_DETECTOR' ) + NAIF_BODY_CODE += ( -42701 ) + + NAIF_BODY_NAME += ( 'IMAP_IDEX_FULL_SCIENCE' ) + NAIF_BODY_CODE += ( -42702 ) + + NAIF_BODY_NAME += ( 'IMAP_GLOWS' ) + NAIF_BODY_CODE += ( -42750 ) + + \begintext + + +IMAP NAIF ID Codes -- Definitions +======================================================================== + + The ID codes -43900 to -43999 have been reserved for the IMAP dynamic + frames kernel and are not utilized in this file. + + The following frames are defined in this kernel file: + + Frame Name Relative To Type NAIF ID + ========================== =============== ======= ======= + + Spacecraft (000-099) + -------------------------- + IMAP_SPACECRAFT J2000 CK -43000 + IMAP_THRUSTER_A1 IMAP_SPACECRAFT FIXED -43010 + IMAP_THRUSTER_A2 IMAP_SPACECRAFT FIXED -43011 + IMAP_THRUSTER_A3 IMAP_SPACECRAFT FIXED -43012 + IMAP_THRUSTER_A4 IMAP_SPACECRAFT FIXED -43013 + IMAP_THRUSTER_R1 IMAP_SPACECRAFT FIXED -43020 + IMAP_THRUSTER_R2 IMAP_SPACECRAFT FIXED -43021 + IMAP_THRUSTER_R3 IMAP_SPACECRAFT FIXED -43022 + IMAP_THRUSTER_R4 IMAP_SPACECRAFT FIXED -43023 + IMAP_THRUSTER_R5 IMAP_SPACECRAFT FIXED -43024 + IMAP_THRUSTER_R6 IMAP_SPACECRAFT FIXED -43025 + IMAP_THRUSTER_R7 IMAP_SPACECRAFT FIXED -43026 + IMAP_THRUSTER_R8 IMAP_SPACECRAFT FIXED -43027 + IMAP_SUN_SENSOR_PZ IMAP_SPACECRAFT FIXED -42030 + IMAP_SUN_SENSOR_MZ IMAP_SPACECRAFT FIXED -42031 + IMAP_STAR_TRACKER_PX IMAP_SPACECRAFT FIXED -42040 + IMAP_STAR_TRACKER_MX IMAP_SPACECRAFT FIXED -42041 + IMAP_LOW_GAIN_ANTENNA IMAP_SPACECRAFT FIXED -42050 + IMAP_MED_GAIN_ANTENNA IMAP_SPACECRAFT FIXED -42051 + IMAP_NUTATION_DAMPER_01 IMAP_SPACECRAFT FIXED -42060 + IMAP_NUTATION_DAMPER_02 IMAP_SPACECRAFT FIXED -42061 + + IMAP-Lo (100-149) + -------------------------- + IMAP_LO_BASE IMAP_SPACECRAFT FIXED -42100 + IMAP_LO_PIVOT IMAP_LO_BASE CK -42101 + IMAP_LO_ENA_SENSOR IMAP_LO_PIVOT FIXED -42102 + IMAP_LO_STAR_SENSOR IMAP_LO_PIVOT FIXED -42103 + + IMAP-Hi (150-199) + -------------------------- + IMAP_HI_45 IMAP_SPACECRAFT FIXED -42150 + IMAP_HI_90 IMAP_SPACECRAFT FIXED -42175 + + IMAP-Ultra (200-249) + -------------------------- + IMAP_ULTRA_45 IMAP_SPACECRAFT FIXED -42200 + IMAP_ULTRA_90 IMAP_SPACECRAFT FIXED -42225 + + MAG (250-299) + -------------------------- + IMAP_MAG IMAP_SPACECRAFT FIXED -42250 + + SWE (300-349) + -------------------------- + IMAP_SWE IMAP_SPACECRAFT FIXED -42300 + IMAP_SWE_DETECTOR_P63 IMAP_SWE FIXED -42301 + IMAP_SWE_DETECTOR_P42 IMAP_SWE FIXED -42302 + IMAP_SWE_DETECTOR_P21 IMAP_SWE FIXED -42303 + IMAP_SWE_DETECTOR_000 IMAP_SWE FIXED -42304 + IMAP_SWE_DETECTOR_M21 IMAP_SWE FIXED -42305 + IMAP_SWE_DETECTOR_M42 IMAP_SWE FIXED -42306 + IMAP_SWE_DETECTOR_M63 IMAP_SWE FIXED -42307 + + SWAPI (350-399) + -------------------------- + IMAP_SWAPI IMAP_SPACECRAFT FIXED -42350 + IMAP_SWAPI_APERTURE_L IMAP_SWAPI FIXED -42351 + IMAP_SWAPI_APERTURE_R IMAP_SWAPI FIXED -42352 + IMAP_SWAPI_SUNGLASSES IMAP_SWAPI FIXED -42353 + + CODICE (400-499) + -------------------------- + IMAP_CODICE IMAP_SPACECRAFT FIXED -42400 + IMAP_CODICE_LO_APERTURE_01 IMAP_CODICE FIXED -42401 + IMAP_CODICE_LO_APERTURE_02 IMAP_CODICE FIXED -42402 + IMAP_CODICE_LO_APERTURE_03 IMAP_CODICE FIXED -42403 + IMAP_CODICE_LO_APERTURE_04 IMAP_CODICE FIXED -42404 + IMAP_CODICE_LO_APERTURE_05 IMAP_CODICE FIXED -42405 + IMAP_CODICE_LO_APERTURE_06 IMAP_CODICE FIXED -42406 + IMAP_CODICE_LO_APERTURE_07 IMAP_CODICE FIXED -42407 + IMAP_CODICE_LO_APERTURE_08 IMAP_CODICE FIXED -42408 + IMAP_CODICE_LO_APERTURE_09 IMAP_CODICE FIXED -42409 + IMAP_CODICE_LO_APERTURE_10 IMAP_CODICE FIXED -42410 + IMAP_CODICE_LO_APERTURE_11 IMAP_CODICE FIXED -42411 + IMAP_CODICE_LO_APERTURE_12 IMAP_CODICE FIXED -42412 + IMAP_CODICE_LO_APERTURE_13 IMAP_CODICE FIXED -42413 + IMAP_CODICE_LO_APERTURE_14 IMAP_CODICE FIXED -42414 + IMAP_CODICE_LO_APERTURE_15 IMAP_CODICE FIXED -42415 + IMAP_CODICE_LO_APERTURE_16 IMAP_CODICE FIXED -42416 + IMAP_CODICE_LO_APERTURE_17 IMAP_CODICE FIXED -42417 + IMAP_CODICE_LO_APERTURE_18 IMAP_CODICE FIXED -42418 + IMAP_CODICE_LO_APERTURE_19 IMAP_CODICE FIXED -42419 + IMAP_CODICE_LO_APERTURE_20 IMAP_CODICE FIXED -42420 + IMAP_CODICE_LO_APERTURE_21 IMAP_CODICE FIXED -42421 + IMAP_CODICE_LO_APERTURE_22 IMAP_CODICE FIXED -42422 + IMAP_CODICE_LO_APERTURE_23 IMAP_CODICE FIXED -42423 + IMAP_CODICE_LO_APERTURE_24 IMAP_CODICE FIXED -42424 + IMAP_CODICE_HI_APERTURE_01 IMAP_CODICE FIXED -42425 + IMAP_CODICE_HI_APERTURE_02 IMAP_CODICE FIXED -42426 + IMAP_CODICE_HI_APERTURE_03 IMAP_CODICE FIXED -42427 + IMAP_CODICE_HI_APERTURE_04 IMAP_CODICE FIXED -42428 + IMAP_CODICE_HI_APERTURE_05 IMAP_CODICE FIXED -42429 + IMAP_CODICE_HI_APERTURE_06 IMAP_CODICE FIXED -42430 + IMAP_CODICE_HI_APERTURE_07 IMAP_CODICE FIXED -42431 + IMAP_CODICE_HI_APERTURE_08 IMAP_CODICE FIXED -42432 + IMAP_CODICE_HI_APERTURE_09 IMAP_CODICE FIXED -42433 + IMAP_CODICE_HI_APERTURE_10 IMAP_CODICE FIXED -42434 + IMAP_CODICE_HI_APERTURE_11 IMAP_CODICE FIXED -42435 + IMAP_CODICE_HI_APERTURE_12 IMAP_CODICE FIXED -42436 + + HIT (500-699) + -------------------------- + IMAP_HIT IMAP_SPACECRAFT FIXED -42500 + IMAP_HIT_L1_APERTURE_01 IMAP_HIT FIXED -42501 + IMAP_HIT_L1_APERTURE_02 IMAP_HIT FIXED -42502 + IMAP_HIT_L1_APERTURE_03 IMAP_HIT FIXED -42503 + IMAP_HIT_L1_APERTURE_04 IMAP_HIT FIXED -42504 + IMAP_HIT_L1_APERTURE_05 IMAP_HIT FIXED -42505 + IMAP_HIT_L1_APERTURE_06 IMAP_HIT FIXED -42506 + IMAP_HIT_L1_APERTURE_07 IMAP_HIT FIXED -42507 + IMAP_HIT_L1_APERTURE_08 IMAP_HIT FIXED -42508 + IMAP_HIT_L1_APERTURE_09 IMAP_HIT FIXED -42509 + IMAP_HIT_L1_APERTURE_10 IMAP_HIT FIXED -42510 + + IDEX (700-749) + -------------------------- + IMAP_IDEX IMAP_SPACECRAFT FIXED -42700 + IMAP_IDEX_DETECTOR IMAP_IDEX FIXED -42701 + IMAP_IDEX_FULL_SCIENCE IMAP_IDEX FIXED -42702 + + GLOWS (750-799) + -------------------------- + IMAP_GLOWS IMAP_SPACECRAFT FIXED -42750 + + +IMAP Frame Tree +======================================================================== + + The diagram below illustrates the IMAP frame hierarchy: + + J2000 + | + |<---ck + | + IMAP_SPACECRAFT + | + IMAP_THRUSTER_A1 + | + |... + | + IMAP_THRUSTER_A4 + | + IMAP_THRUSTER_R1 + | + |... + | + IMAP_THRUSTER_R8 + | + IMAP_SUN_SENSOR_PZ + | + IMAP_SUN_SENSOR_MZ + | + IMAP_STAR_TRACKER_PX + | + IMAP_STAR_TRACKER_MX + | + IMAP_LOW_GAIN_ANTENNA + | + IMAP_MED_GAIN_ANTENNA + | + IMAP_NUTATION_DAMPER_01 + | + IMAP_NUTATION_DAMPER_02 + | + IMAP_LO_BASE + | | + | |<---ck + | | + | IMAP_LO_PIVOT + | | + | IMAP_LO_ENA_SENSOR + | | + | IMAP_LO_STAR_SENSOR + | + IMAP_HI_45 + | + IMAP_HI_90 + | + IMAP_ULTRA_45 + | + IMAP_ULTRA_90 + | + IMAP_MAG + | + IMAP_SWE + | | + | IMAP_SWE_DETECTOR_P63 + | | + | IMAP_SWE_DETECTOR_P42 + | | + | IMAP_SWE_DETECTOR_P21 + | | + | IMAP_SWE_DETECTOR_000 + | | + | IMAP_SWE_DETECTOR_M21 + | | + | IMAP_SWE_DETECTOR_M42 + | | + | IMAP_SWE_DETECTOR_M63 + | + IMAP_SWAPI + | | + | IMAP_SWAPI_APERTURE_L + | | + | IMAP_SWAPI_APERTURE_R + | | + | IMAP_SWAPI_SUNGLASSES + | + IMAP_CODICE + | | + | IMAP_CODICE_LO_APERTURE_01 + | | + | |... + | | + | IMAP_CODICE_LO_APERTURE_24 + | | + | IMAP_CODICE_HI_APERTURE_01 + | | + | |... + | | + | IMAP_CODICE_HI_APERTURE_12 + | + IMAP_HIT + | | + | IMAP_HIT_L1_APERTURE_01 + | | + | |... + | | + | IMAP_HIT_L1_APERTURE_10 + | + IMAP_IDEX + | | + | IMAP_IDEX_DETECTOR + | | + | IMAP_IDEX_FULL_SCIENCE + | + IMAP_GLOWS + + +IMAP Spacecraft Frame +======================================================================== + + The orientation of the spacecraft body frame with respect to an + inertial frame, J2000 for IMAP, is provided by a C-kernel (see [3] + for details). + + The spacecraft coordinate frames are defined by the IMAP control + documents (see [4,5], NB, figure 2.2). There are two frames described + there: Observatory Mechanical Design Reference Frame (most relevant) + and Observatory Pointing and Dynamics Reference Frame (less relevant + for this frame kernel). + + + Observatory Mechanical Design Reference Frame (IMAP_SPACECRAFT) + --------------------------------------------------------------------- + + If not explicitly stated, references to 'spacecraft mechanical frame' + 'spacecraft frame', or 'S/C frame' will refer to this frame. + + All instruments and component placements and orientations are defined + using this coordinate frame reference. + + Origin: Center of the launch vehicle adapter ring at the + observatory/launch vehicle interface plane + + +Z axis: Perpendicular to the launch vehicle interface plane pointed + in the direction of the top deck (runs through the center + of the central cylinder structure element) + + +Y axis: Direction of the vector orthogonal to the +Z axis and + parallel to the deployed MAG boom + + +X axis: The third orthogonal axis defined using an X, Y, Z ordered + right hand rule + + NB: The Observatory Pointing and Dynamics Reference Frame is also + defined in [5]. It is identical to the observatory mechanical design + reference frame, but with the origin translated to the observatory + center of mass (which changes with boom deployment and fuel usage). + The offset difference between the mechanical and dynamic frame is + within the uncertainty range of the ephemeris, so the mechanical + design frame is used here for definiteness. + + Three different views [5,6] of the spacecraft with labeled components + are presented below for illustrative purposes. + + + IMAP -Z Bottom View (Figure 3-2 in [5], G-G in [6] rotated 180°) + --------------------------------------------------------------------- + --------- + | +X axis | -------------------- + --------- | +Z axis facing Sun | + . | into page | + /|\ -------------------- + | + | + | + _ + HI 45 /`~~__HI 90 `+ direction of + , = .^ - /_ ``-. '. positive + .+ + `^~/ ./ ~ rotation + ^ + + . -- ' `` \ _-~ \ + _ / ',= ' \~'` \ IMAP \ + ULTRA /' '-_ .~ ' \,.=.. \ LO \|/ + 90 / ~ _,.,_ + + \ ' + / ,~' +' `'+ + + \ + / ~^ .' , = .'. '- ='' -`` --------- + ^/ / , = . + + \ \~'` | +Y axis |-----> + | . + + + + . \ --------- ___ + | | + + ' = ' | \--------------------| | + SWAPI| | ' = ', - . | /--------------------|___| + _+_: ' + + ' / MAG boom + \_ __\__ \ + + / /^*~, + + | SWE '. ' = ' .' ULTRA / + `~-' '~..,___,..~' 45 /~,* + _\ / /~,*` + * / CODICE ^*._/ *` HIT + *\ _/`. / + * / /~ _ _ ,.-^-., _ _ _ / + '=' + + + GLOWS + + + '-.,.-' + IDEX + + + IMAP +X Side View (F-F in [6]) + --------------------------------------------------------------------- + --------- + | +Z axis | + --------- --------------------- + . | +X axis out of page | + /|\ --------------------- + | LGA + __________________|______|^|_________ ___ + SWAPI|__________________|__________________|====================| | + #|-| | | .-==-, | / MAG boom '---' + #|-| {|## | | / \ | | + | {|## | |{ HI 90 }| IMAP LO| + | {|## | _.._ | \ / | _., | + | ULTRA | / \ | `-==-' | / __`',| + | 90 | \ HI 45/ | | \ \_\ ;| + | | '----` | | ~._ + | + '-------------------|----------/--------' + | | \_________O_________/ | | ----------------> + |__| ----------- /_\ --------- + STAR | S/C FRAME | MGA | +Y axis | + TRACKERS | ORIGIN | --------- + ----------- + + + IMAP -X Side View (C-C in [6]) + --------------------------------------------------------------------- + --------- + | +Z axis | + ------------------- --------- + | +X axis into page | . + ------------------- /|\ + LGA | + ___ _________|^|______|__________________ + | |====================|__________________|_____________ __ _|SWAPI + '---' MAG boom \ __ | | | // \ /--|# + |( )=|__|| | | \\__/ \--|# + | HIT | _|_ IDEX | CODICE | + | | ,.' | '., | | + | ____ | [ \ | / ] | SWE| + ULTRA ##',', |,.'|'.,| GLOWS (#)| + 45 ####'. + | + \\(O) |-|| + '----####/----- + | + --------------' + <---------------- | | \______'-.O.-'______/ | | + --------- /_\ ----------- |__| + | +Y axis | MGA | S/C FRAME | STAR + --------- | ORIGIN | TRACKERS + ----------- + + + IMAP Component Location and Orientation + --------------------------------------------------------------------- + + Payload and subsystem component locations are specified[5,6] in the + Observatory Mechanical Design Reference Frame (described above). + Boresights are defined in azimuth and elevation (and resultant + direction cosign matrices) of these angles[6] in the same reference + frame. The azimuth and elevation angle diagram is provided below. + + In general, descriptions in this kernel treat the +Z direction as + "up" and the -Z direction as "down." Locations referred to as "above" + are generally closer to the Sun, and vice versa for "below." The + "upper" side of the spacecraft is the plane of the solar panels, + while the "lower" side may refer to the area near the adapter ring. + If ambiguity could arise, more thorough descriptions will be used. + + + Toward Sun + + +Z axis + . + | + . + | + . Component + | Location/ + . Orientation + | @ + Toward . .'| + MAG | +` | + .~ '` Boom S/C . .` \ | + .~ '` FRAME |.` : | + / ~'` ORIGIN O | | + *--- .~ '` \ Elevation + .~ '` \ | | + .~ '` \ ; |~ + .~ '\ \ / | ^~ + +Y axis \ \ + | ^~ + '. '~, \ | ^~ + '~ Azimuth \ | ^~ + '~. `^~-> \| -X axis + ' ~ ., _ _ ,.~ + ``'`` + + + \begindata + + FRAME_IMAP_SPACECRAFT = -43000 + FRAME_-43000_NAME = 'IMAP_SPACECRAFT' + FRAME_-43000_CLASS = 3 + FRAME_-43000_CLASS_ID = -43000 + FRAME_-43000_CENTER = -43 + CK_-43000_SCLK = -43 + CK_-43000_SPK = -43 + + \begintext + + +IMAP Thruster Frames +======================================================================== + + There are four axial (A) thrusters and eight radial (R) thrusters on + IMAP[6]. The table below shows the thruster positions defined in the + spacecraft frame[6], at the intersection of the thrust axis and the + nozzle exit plane. The unit direction vectors listed in the table + below point in the direction of the thruster exhaust. The positional + information is captured in the IMAP structure SPK, while the + orientation information is captured here. + + + Thruster ID X (mm) Y (mm) Z (mm) UnitDir (X,Y,Z) + ---------------- ------ -------- -------- ------- --------------- + IMAP_THRUSTER_A1 -43010 1007.28 516.50 1312.40 ( 0, 0, 1 ) + IMAP_THRUSTER_A2 -43011 -1007.28 -516.50 1312.40 ( 0, 0, 1 ) + IMAP_THRUSTER_A3 -43012 -1007.28 -516.50 101.77 ( 0, 0, -1 ) + IMAP_THRUSTER_A4 -43013 1007.28 516.50 101.77 ( 0, 0, -1 ) + IMAP_THRUSTER_R1 -43020 -126.90 1237.78 841.12 (-0.5, 0.866,0) + IMAP_THRUSTER_R2 -43021 126.90 -1237.78 841.12 ( 0.5,-0.866,0) + IMAP_THRUSTER_R3 -43022 -1008.49 728.79 841.12 (-0.5, 0.866,0) + IMAP_THRUSTER_R4 -43023 1008.49 -728.79 841.12 ( 0.5,-0.866,0) + IMAP_THRUSTER_R5 -43024 -126.90 1237.78 447.42 (-0.5, 0.866,0) + IMAP_THRUSTER_R6 -43025 126.90 -1237.78 447.42 ( 0.5,-0.866,0) + IMAP_THRUSTER_R7 -43026 -1008.49 728.79 447.42 (-0.5, 0.866,0) + IMAP_THRUSTER_R8 -43027 1008.49 -728.79 447.42 ( 0.5,-0.866,0) + + + Thruster Locations and Directions + --------------------------------------------------------------------- + + The four axial thrusters[6] are directed along the spacecraft Z axis, + with A1,A2 located on the +Z side of the spacecraft and A3,A4 located + on the -Z side. A1,A2 fire in the +Z direction, while A3,A4 fire in + the -Z direction. A1 and A4 are aligned in the Z direction, while + A2 and A3 are aligned but on the opposite side of the S/C as A1/A4. + + The eight radial thrusters[6] are grouped into four pairs (R1/R5, + R2/R6, R3/R7, R4/R8); each pair is aligned along the Z direction and + fire in the same direction. There are two distinct firing directions, + all perpendicular to the spacecraft Z axis: R1/R5 & R3/R7 fire toward + the +Y direction (with a slight -X component), while R2/R6 & R4/R8 + fire in the -Y direction (with a slight +X component). Thrusters + R1-R4 are located above the center of mass (towards the Sun), while + thrusters R5-R8 are located below the center of mass (away from the + Sun). The table below shows the azimuth of location and direction of + radial thrusters calculated from using thruster table above. + + + Location Azim Direction Azim + -------------- -------------- + R1/R5 5.85° 30.0° + R2/R6 180° + 5.85° 180° + 30.0° + R3/R7 54.15° 30.0° + R4/R8 180° + 54.15° 180° + 30.0° + + + +X axis +Z axis facing Sun + . into page + /|\ + | + | + | A1 (on +Z side) + A4 (on -Z side) + R4/R8 Dir /`~~__ / + '~._ , = .^ - /_ ``-. / + /~._ .+ + `^~/ .\/ + 30°| '~. + . -- ' `` @\ _-~ + - - + - - - -# R4/R8 \~'` \ + /' '-_ . \,.=.. \ + / ~ _,.,_ + + \ + R2/R6 Dir / ,~' +' `'+ + + \ + '~._ / ~^ .' , = .'. '- ='' -`` + /~._ ^/ / , = . + + \ \~'` + 30°| '~. | . + + + + . \ +Y axis -----> + - - + - - - -|# R2/R6 | + + ' = ' | \ + | | ' = ', - . | R1/R5 #._- - - - - + - - + _+_: ' + + ' / '~._ | + \_ __\__ \ + + / /^*~, '~._ / 30° + + | \ '. ' = ' .' / / '~. + `~-' '~..,___,..~' / /~,* R1/R5 Dir + _\ / /~,*` + * / \ ^*._/ *` + *\ _/`. R3/R7 #/._- - - - - + - - + * / /\@_ _ ,.-^-., _ _ _ / '~._ | + '=' | + + '~._ / 30° + | + + '~. + | '-.,.-' R3/R7 Dir + | + A2 (on +Z side) + A3 (on -Z side) + + + Axial Thruster Frames + --------------------------------------------------------------------- + + Each axial thruster has a frame defined so that the thruster exhaust + exits in the +Z' direction. The +Y' axis is chosen to lie in the + direction of the MAG boom. X' = Y' x Z' completes the frame. + + [X] [ 1 0 0 ] [X'] + [Y] = [ 0 1 0 ] [Y'] + [Z]S/C [ 0 0 1 ] [Z']Axial Thrusters A1,A2 + + [X] [ -1 0 0 ] [X'] + [Y] = [ 0 1 0 ] [Y'] + [Z]S/C [ 0 0 -1 ] [Z']Axial Thrusters A3,A4 + + + Axial Thruster + Exhaust Direction + + +Z' axis + | + | + _. -|- ._ + ,' | ', + |, | ,| + | ' -.,_|_,.- ' | + ' ' + \ / + \ / + \ / + \ / + \ / Toward + ',_,' ^~ MAG + .~ '` ^~ ^~ Boom + .~ '` ^~ ^~ + .~ '` ^~ ^~ + .~ '` ^~ ^~ \ + +X' axis ^~ --* + ^~ + ^~ + +Y' axis + + + \begindata + + FRAME_IMAP_THRUSTER_A1 = -43010 + FRAME_-43010_NAME = 'IMAP_THRUSTER_A1' + FRAME_-43010_CLASS = 4 + FRAME_-43010_CLASS_ID = -43010 + FRAME_-43010_CENTER = -43 + TKFRAME_-43010_RELATIVE = 'IMAP_SPACECRAFT' + TKFRAME_-43010_SPEC = 'MATRIX' + TKFRAME_-43010_MATRIX = ( 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1 ) + + FRAME_IMAP_THRUSTER_A2 = -43011 + FRAME_-43011_NAME = 'IMAP_THRUSTER_A2' + FRAME_-43011_CLASS = 4 + FRAME_-43011_CLASS_ID = -43011 + FRAME_-43011_CENTER = -43 + TKFRAME_-43011_RELATIVE = 'IMAP_SPACECRAFT' + TKFRAME_-43011_SPEC = 'MATRIX' + TKFRAME_-43011_MATRIX = ( 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1 ) + + FRAME_IMAP_THRUSTER_A3 = -43012 + FRAME_-43012_NAME = 'IMAP_THRUSTER_A3' + FRAME_-43012_CLASS = 4 + FRAME_-43012_CLASS_ID = -43012 + FRAME_-43012_CENTER = -43 + TKFRAME_-43012_RELATIVE = 'IMAP_SPACECRAFT' + TKFRAME_-43012_SPEC = 'MATRIX' + TKFRAME_-43012_MATRIX = ( -1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + -1 ) + + FRAME_IMAP_THRUSTER_A4 = -43013 + FRAME_-43013_NAME = 'IMAP_THRUSTER_A4' + FRAME_-43013_CLASS = 4 + FRAME_-43013_CLASS_ID = -43013 + FRAME_-43013_CENTER = -43 + TKFRAME_-43013_RELATIVE = 'IMAP_SPACECRAFT' + TKFRAME_-43013_SPEC = 'MATRIX' + TKFRAME_-43013_MATRIX = ( -1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + -1 ) + + \begintext + + + Radial Thrusters + --------------------------------------------------------------------- + + Each radial thruster has a frame defined so that the thruster exhaust + exits in the +Y' direction. The +Z' axis is chosen to lie along the + spacecraft +Z axis (toward Sun). X' = Y' x Z' completes the frame. + + [X] [ cos( 30) -sin( 30) 0 ] [X'] + [Y] = [ sin( 30) cos( 30) 0 ] [Y'] + [Z]S/C [ 0 0 1 ] [Z']Rad. Thrusters R1,R3,R5,R7 + + [X] [ cos(210) -sin(210) 0 ] [X'] + [Y] = [ sin(210) cos(210) 0 ] [Y'] + [Z]S/C [ 0 0 1 ] [Z']Rad. Thrusters R2,R4,R6,R8 + + + Toward Sun + + +Z' axis + . + | + . + | + . + | + . + Radial Thruster | + Exhaust Direction . + | + .~ '` . + /.~ '` _,,~ ~ ~ ~ ~ ~ ~ ~ | + *-- .;-. \ ~ + ,' '. ~ ^~ + ; \ ~' ^~ + | .~ '`: ~' ^~ + .~ '` | ~' ^~ + ~ '` \ ; _ ~' ^~ + +Y' axis '.,_._;-' ^~ + ^~ + -X' axis + + + \begindata + + FRAME_IMAP_THRUSTER_R1 = -43020 + FRAME_-43020_NAME = 'IMAP_THRUSTER_R1' + FRAME_-43020_CLASS = 4 + FRAME_-43020_CLASS_ID = -43020 + FRAME_-43020_CENTER = -43 + TKFRAME_-43020_RELATIVE = 'IMAP_SPACECRAFT' + TKFRAME_-43020_SPEC = 'MATRIX' + TKFRAME_-43020_MATRIX = ( 0.86602540378443865, + 0.50000000000000000, + 0.00000000000000000, + -0.50000000000000000, + 0.86602540378443865, + 0.00000000000000000, + 0.00000000000000000, + 0.00000000000000000, + 1.00000000000000000 ) + + FRAME_IMAP_THRUSTER_R2 = -43021 + FRAME_-43021_NAME = 'IMAP_THRUSTER_R1' + FRAME_-43021_CLASS = 4 + FRAME_-43021_CLASS_ID = -43021 + FRAME_-43021_CENTER = -43 + TKFRAME_-43021_RELATIVE = 'IMAP_SPACECRAFT' + TKFRAME_-43021_SPEC = 'MATRIX' + TKFRAME_-43021_MATRIX = ( -0.86602540378443865, + -0.50000000000000000, + 0.00000000000000000, + 0.50000000000000000, + -0.86602540378443865, + 0.00000000000000000, + 0.00000000000000000, + 0.00000000000000000, + 1.00000000000000000 ) + + FRAME_IMAP_THRUSTER_R3 = -43022 + FRAME_-43022_NAME = 'IMAP_THRUSTER_R3' + FRAME_-43022_CLASS = 4 + FRAME_-43022_CLASS_ID = -43022 + FRAME_-43022_CENTER = -43 + TKFRAME_-43022_RELATIVE = 'IMAP_SPACECRAFT' + TKFRAME_-43022_SPEC = 'MATRIX' + TKFRAME_-43022_MATRIX = ( 0.86602540378443865, + 0.50000000000000000, + 0.00000000000000000, + -0.50000000000000000, + 0.86602540378443865, + 0.00000000000000000, + 0.00000000000000000, + 0.00000000000000000, + 1.00000000000000000 ) + + FRAME_IMAP_THRUSTER_R4 = -43023 + FRAME_-43023_NAME = 'IMAP_THRUSTER_R4' + FRAME_-43023_CLASS = 4 + FRAME_-43023_CLASS_ID = -43023 + FRAME_-43023_CENTER = -43 + TKFRAME_-43023_RELATIVE = 'IMAP_SPACECRAFT' + TKFRAME_-43023_SPEC = 'MATRIX' + TKFRAME_-43023_MATRIX = ( -0.86602540378443865, + -0.50000000000000000, + 0.00000000000000000, + 0.50000000000000000, + -0.86602540378443865, + 0.00000000000000000, + 0.00000000000000000, + 0.00000000000000000, + 1.00000000000000000 ) + + FRAME_IMAP_THRUSTER_R5 = -43024 + FRAME_-43024_NAME = 'IMAP_THRUSTER_R5' + FRAME_-43024_CLASS = 4 + FRAME_-43024_CLASS_ID = -43024 + FRAME_-43024_CENTER = -43 + TKFRAME_-43024_RELATIVE = 'IMAP_SPACECRAFT' + TKFRAME_-43024_SPEC = 'MATRIX' + TKFRAME_-43024_MATRIX = ( 0.86602540378443865, + 0.50000000000000000, + 0.00000000000000000, + -0.50000000000000000, + 0.86602540378443865, + 0.00000000000000000, + 0.00000000000000000, + 0.00000000000000000, + 1.00000000000000000 ) + + FRAME_IMAP_THRUSTER_R6 = -43025 + FRAME_-43025_NAME = 'IMAP_THRUSTER_R6' + FRAME_-43025_CLASS = 4 + FRAME_-43025_CLASS_ID = -43025 + FRAME_-43025_CENTER = -43 + TKFRAME_-43025_RELATIVE = 'IMAP_SPACECRAFT' + TKFRAME_-43025_SPEC = 'MATRIX' + TKFRAME_-43025_MATRIX = ( -0.86602540378443865, + -0.50000000000000000, + 0.00000000000000000, + 0.50000000000000000, + -0.86602540378443865, + 0.00000000000000000, + 0.00000000000000000, + 0.00000000000000000, + 1.00000000000000000 ) + + FRAME_IMAP_THRUSTER_R7 = -43026 + FRAME_-43026_NAME = 'IMAP_THRUSTER_R7' + FRAME_-43026_CLASS = 4 + FRAME_-43026_CLASS_ID = -43026 + FRAME_-43026_CENTER = -43 + TKFRAME_-43026_RELATIVE = 'IMAP_SPACECRAFT' + TKFRAME_-43026_SPEC = 'MATRIX' + TKFRAME_-43026_MATRIX = ( 0.86602540378443865, + 0.50000000000000000, + 0.00000000000000000, + -0.50000000000000000, + 0.86602540378443865, + 0.00000000000000000, + 0.00000000000000000, + 0.00000000000000000, + 1.00000000000000000 ) + + FRAME_IMAP_THRUSTER_R8 = -43027 + FRAME_-43027_NAME = 'IMAP_THRUSTER_R6' + FRAME_-43027_CLASS = 4 + FRAME_-43027_CLASS_ID = -43027 + FRAME_-43027_CENTER = -43 + TKFRAME_-43027_RELATIVE = 'IMAP_SPACECRAFT' + TKFRAME_-43027_SPEC = 'MATRIX' + TKFRAME_-43027_MATRIX = ( -0.86602540378443865, + -0.50000000000000000, + 0.00000000000000000, + 0.50000000000000000, + -0.86602540378443865, + 0.00000000000000000, + 0.00000000000000000, + 0.00000000000000000, + 1.00000000000000000 ) + + \begintext + + +IMAP Sun Sensor Frames +======================================================================== + + There are two digital sun sensors (DSS): one on the +Z side of the + spacecraft pointing in +Z direction, and one on the -Z side pointing + mostly in the radial direction with a mild tilt in the -Z direction. + The positional information is captured in the IMAP structure SPK, + while the orientation information is captured here. + + Each DSS has a frame defined so that the look-direction is along the + +Z' axis (toward Sun). The digital image rows and columns are aligned + with the X' and Y' axes of the frame. + + [X] [ cos(az) -sin(az) 0 ] [X'] + [Y] = [ sin(az) cos(az) 0 ] [Y'] + [Z]S/C [ 0 0 1 ] [Z']Digital Sun Sensor + + +IMAP Star Trackers Frames +======================================================================== + + +IMAP Antenna Frames +======================================================================== + + +IMAP-Lo Frames +======================================================================== + + TODO: FIX ME...The orientation of the spacecraft body frame with + respect to an inertial + frame, for IMAP - ECLIPJ2000, is provided by a C-kernel (see [3] + for details). + + This frame specifies the rotating X,Y and pointing Z coordinate body + frame. + + \begindata + + FRAME_IMAP_LO_BASE = -43100 + FRAME_-43100_NAME = 'IMAP_LO_BASE' + FRAME_-43100_CLASS = 4 + FRAME_-43100_CLASS_ID = -43100 + FRAME_-43100_CENTER = -43 + TKFRAME_-43100_SPEC = 'MATRIX' + TKFRAME_-43100_MATRIX = ( -0.866025, + 0.500000, + 0.000000, + -0.500000, + -0.866025, + 0.000000, + 0.000000, + 0.000000, + 1.000000 ) + TKFRAME_-43100_RELATIVE = 'IMAP_SPACECRAFT' + + \begintext + + +IMAP-Hi Frames +======================================================================== + + TODO: general discussion of Ultra. + + + IMAP-Hi 45 Frames + ===================================================================== + + \begindata + + FRAME_IMAP_HI_45 = -43150 + FRAME_-43150_NAME = 'IMAP_HI_45' + FRAME_-43150_CLASS = 4 + FRAME_-43150_CLASS_ID = -43150 + FRAME_-43150_CENTER = -43 + TKFRAME_-43150_SPEC = 'MATRIX' + TKFRAME_-43150_MATRIX = ( 0.066987, + -0.250000, + 0.965926, + 0.965926, + 0.258819, + 0.000000, + -0.250000, + 0.933013, + 0.258819 ) + TKFRAME_-43150_RELATIVE = 'IMAP_SPACECRAFT' + + \begintext + + + IMAP-Hi 90 Frames + ===================================================================== + + TODO: FIX ME...The orientation of the spacecraft body frame with + respect to an inertial + frame, for IMAP - ECLIPJ2000, is provided by a C-kernel (see [3] + for details). + + This frame specifies the rotating X,Y and pointing Z coordinate body + frame. + + \begindata + + FRAME_IMAP_HI_90 = -43160 + FRAME_-43160_NAME = 'IMAP_HI_90' + FRAME_-43160_CLASS = 4 + FRAME_-43160_CLASS_ID = -43160 + FRAME_-43160_CENTER = -43 + TKFRAME_-43160_SPEC = 'MATRIX' + TKFRAME_-43160_MATRIX = ( -0.668531, + 0.233315, + -0.706138, + 0.683013, + -0.183013, + -0.707107, + -0.294210, + -0.955024, + -0.037007 ) + TKFRAME_-43160_RELATIVE = 'IMAP_SPACECRAFT' + + \begintext + + +IMAP-Ultra Frames +======================================================================== + + TODO: general discussion of Ultra. + + + IMAP-Ultra 45 Frames + ===================================================================== + + TODO: add diagrams + + ULTRA-45 has the following nominal alignment to the spacecraft frame, + reference Table 1 of [6]. The azimuth and elevation angles are + illustrated in the 'IMAP I&T Component Placement' section near the top + of this document. + + azimuth | elevation + (deg) | (deg) + ---------+--------- + 127 | 15 + + The ULTRA-45 base frame is defined by the instrument team as follows [10]: + + * +Z axis is the boresight (center axis of the instrument pointing + away from the spacecraft body). + * +X axis is along the instrument slit, in the anti-sunward direction. + + The azimuth and elevation give the instrument boresight vector, +Z in + the instrument frame: + + Z = [ -sin(az) * cos(el), cos(az) * cos(el), sin(el) ] + instr + + The instrument +X axis is in the anti-sunward direction, towards the + spacecraft -Z axis: + + X = [ 0 0 -1 ] + instr + + Taking the cross product and normalizing, we arrive at the instrumet +Y + axis: + Z x X + Y = --------- + instr | Z x X | + + And adjusting X: + + Y x Z + X = --------- + instr | Y x Z | + + This definition is captured in the keywords below. + + \begindata + + FRAME_IMAP_ULTRA_45 = -43200 + FRAME_-43200_NAME = 'IMAP_ULTRA_45' + FRAME_-43200_CLASS = 4 + FRAME_-43200_CLASS_ID = -43200 + FRAME_-43200_CENTER = -43 + TKFRAME_-43200_SPEC = 'MATRIX' + TKFRAME_-43200_MATRIX = ( 0.385117954958023, + -0.593029645775782, + -0.707106781186548, + -0.838670567945424, + -0.544639035015027, + -0.000000000000000, + -0.385117954958023, + 0.593029645775783, + -0.707106781186547 ) + TKFRAME_-43200_RELATIVE = 'IMAP_SPACECRAFT' + + \begintext + + + IMAP-Ultra 45 Frames + ===================================================================== + + TODO: FIX ME...The orientation of the spacecraft body frame with + respect to an inertial + frame, for IMAP - ECLIPJ2000, is provided by a C-kernel (see [3] + for details). + + This frame specifies the rotating X,Y and pointing Z coordinate body + frame. + + \begindata + + FRAME_IMAP_ULTRA_90 = -43210 + FRAME_-43210_NAME = 'IMAP_ULTRA_90' + FRAME_-43210_CLASS = 4 + FRAME_-43210_CLASS_ID = -43210 + FRAME_-43210_CENTER = -43 + TKFRAME_-43210_SPEC = 'MATRIX' + TKFRAME_-43210_MATRIX = ( 0.000000, + 0.000000, + 1.000000, + -0.866025, + -0.500000, + 0.000000, + 0.500000, + -0.866025, + 0.000000 ) + TKFRAME_-43210_RELATIVE = 'IMAP_SPACECRAFT' + + \begintext + + +IMAP Magnetometer (MAG) Frames +======================================================================== + + TODO: FIX ME...The orientation of the spacecraft body frame with + respect to an inertial + frame, for IMAP - ECLIPJ2000, is provided by a C-kernel (see [3] + for details). + + Basically just maps Z-inst to Y-body + + This frame specifies the rotating X,Y and pointing Z coordinate body + frame. + + \begindata + + FRAME_IMAP_MAG = -43250 + FRAME_-43250_NAME = 'IMAP_MAG' + FRAME_-43250_CLASS = 4 + FRAME_-43250_CLASS_ID = -43250 + FRAME_-43250_CENTER = -43 + TKFRAME_-43250_SPEC = 'MATRIX' + TKFRAME_-43250_MATRIX = ( 0.000000, + -1.000000, + 0.000000, + -1.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + -1.000000 ) + TKFRAME_-43250_RELATIVE = 'IMAP_SPACECRAFT' + +\begintext + + +IMAP Solar Wind Electron (SWE) Frames +======================================================================== + + TODO: FIX ME...The orientation of the spacecraft body frame with + respect to an inertial + frame, for IMAP - ECLIPJ2000, is provided by a C-kernel (see [3] + for details). + + This frame specifies the rotating X,Y and pointing Z coordinate body + frame. + + \begindata + + FRAME_IMAP_SWE = -43300 + FRAME_-43300_NAME = 'IMAP_SWE' + FRAME_-43300_CLASS = 4 + FRAME_-43300_CLASS_ID = -43300 + FRAME_-43300_CENTER = -43 + TKFRAME_-43300_SPEC = 'MATRIX' + TKFRAME_-43300_MATRIX = ( 0.453990, + 0.891007, + 0.000000, + -0.891007, + 0.453990, + 0.000000, + 0.000000, + 0.000000, + 1.000000 ) + TKFRAME_-43300_RELATIVE = 'IMAP_SPACECRAFT' + +\begintext + + +IMAP Solar Wind and Pickup Ion (SWAPI) Frames +======================================================================== + + TODO: add diagrams + + SWAPI has the following nominal alignment to the spacecraft frame, + reference Table 1 of [6]. The azimuth and elevation angles are + illustrated in the 'IMAP I&T Component Placement' section near the top + of this document. + + azimuth | elevation + (deg) | (deg) + ---------+--------- + 168 | 0 + + The SWAPI base frame is defined in the instrument MICD [8] as follows: + + * -Z axis is the axis of symmetry of the instrument, pointing + away from the spacecraft body. + * +Y axis is along the aperture center, in the anti-sunward direction. + + The azimuth and elevation give the outward axis of symmetry, -Z in the + instrument frame: + + -Z = -[ -sin(az) * cos(el), cos(az) * cos(el), sin(el) ] + instr + + The instrument +Y axis is in the sunward direction, towards the + spacecraft +Z axis: + + Y = [ 0 0 1 ] + instr + + Taking the cross product and normalizing, we arrive at the instrumet +X + axis: + Y x Z + X = --------- + instr | Y x Z | + + And adjusting Y: + + Z x X + Y = --------- + instr | Z x X | + + This definition is captured in the keywords below. + + \begindata + + FRAME_IMAP_SWAPI = -43350 + FRAME_-43350_NAME = 'IMAP_SWAPI' + FRAME_-43350_CLASS = 4 + FRAME_-43350_CLASS_ID = -43350 + FRAME_-43350_CENTER = -43 + TKFRAME_-43350_SPEC = 'MATRIX' + TKFRAME_-43350_MATRIX = ( -0.97814760073381, + 0.20791169081776, + 0.00000000000000, + 0.00000000000000, + 0.00000000000000, + 1.00000000000000, + 0.20791169081776, + 0.97814760073381, + 0.00000000000000 ) + TKFRAME_-43350_RELATIVE = 'IMAP_SPACECRAFT' + +\begintext + + +IMAP Compact Dual Ion Composition Experiment (CoDICE) Frames +======================================================================== + + TODO: FIX ME...The orientation of the spacecraft body frame with + respect to an inertial + frame, for IMAP - ECLIPJ2000, is provided by a C-kernel (see [3] + for details). + + This frame specifies the rotating X,Y and pointing Z coordinate body + frame. + + \begindata + + FRAME_IMAP_CODICE = -43400 + FRAME_-43400_NAME = 'IMAP_CODICE' + FRAME_-43400_CLASS = 4 + FRAME_-43400_CLASS_ID = -43400 + FRAME_-43400_CENTER = -43 + TKFRAME_-43400_SPEC = 'MATRIX' + TKFRAME_-43400_MATRIX = ( 0.694626, + 0.719371, + 0.000000, + -0.719371, + 0.694626, + 0.000000, + 0.000000, + 0.000000, + 1.000000 ) + TKFRAME_-43400_RELATIVE = 'IMAP_SPACECRAFT' + +\begintext + + +IMAP High-energy Ion Telescope (HIT) Frames +======================================================================== + + TODO: FIX ME...The orientation of the spacecraft body frame with + respect to an inertial + frame, for IMAP - ECLIPJ2000, is provided by a C-kernel (see [3] + for details). + + This frame specifies the rotating X,Y and pointing Z coordinate body + frame. + + \begindata + + FRAME_IMAP_HIT = -43500 + FRAME_-43500_NAME = 'IMAP_HIT' + FRAME_-43500_CLASS = 4 + FRAME_-43500_CLASS_ID = -43500 + FRAME_-43500_CENTER = -43 + TKFRAME_-43500_SPEC = 'MATRIX' + TKFRAME_-43500_MATRIX = ( 0.866025, + 0.500000, + 0.000000, + -0.500000, + 0.866025, + 0.000000, + 0.000000, + 0.000000, + 1.000000 ) + TKFRAME_-43500_RELATIVE = 'IMAP_SPACECRAFT' + +\begintext + + +IMAP Interstellar Dust Experiment (IDEX) Frames +======================================================================== + + TODO: FIX ME...The orientation of the spacecraft body frame with + respect to an inertial + frame, for IMAP - ECLIPJ2000, is provided by a C-kernel (see [3] + for details). + + This frame specifies the rotating X,Y and pointing Z coordinate body + frame. + + \begindata + + FRAME_IMAP_IDEX = -43700 + FRAME_-43700_NAME = 'IMAP_IDEX' + FRAME_-43700_CLASS = 4 + FRAME_-43700_CLASS_ID = -43700 + FRAME_-43700_CENTER = -43 + TKFRAME_-43700_SPEC = 'MATRIX' + TKFRAME_-43700_MATRIX = ( 0.000000, + 1.000000, + 0.000000, + -0.707107, + 0.000000, + -0.707107, + -0.707107, + 0.000000, + 0.707107 ) + TKFRAME_-43700_RELATIVE = 'IMAP_SPACECRAFT' + +\begintext + + +IMAP GLObal solar Wind Structure (GLOWS) Frames +======================================================================== + + TODO: add diagrams + + GLOWS has the following nominal alignment to the spacecraft frame, + reference Table 1 of [6]. The azimuth and elevation angles are + illustrated in the 'IMAP I&T Component Placement' section near the top + of this document. + + azimuth | elevation + (deg) | (deg) + ---------+--------- + 127 | 15 + + The GLOWS base frame is defined by the instrument team as follows [10]: + + * +Z axis points in the anti-boresight direction + * +Y axis points in the anti-sunward direction. + + The azimuth and elevation give the outward axis of symmetry, -Z in the + instrument frame: + + Z = -[ -sin(az) * cos(el), cos(az) * cos(el), sin(el) ] + instr + + The instrument +Y axis is in the anti-sunward direction, towards the + spacecraft -Z axis: + + Y = [ 0 0 -1 ] + instr + + Taking the cross product and normalizing, we arrive at the instrumet +X + axis: + Y x Z + X = --------- + instr | Y x Z | + + And adjusting Y: + + Z x X + Y = --------- + instr | Z x X | + + This definition is captured in the keywords below. + + \begindata + + FRAME_IMAP_GLOWS = -43750 + FRAME_-43750_NAME = 'IMAP_GLOWS' + FRAME_-43750_CLASS = 4 + FRAME_-43750_CLASS_ID = -43750 + FRAME_-43750_CENTER = -43 + TKFRAME_-43750_SPEC = 'MATRIX' + TKFRAME_-43750_MATRIX = ( 0.60181502315205, + -0.79863551004729, + 0.00000000000000, + -0.20670208009540, + -0.15576118962056, + -0.96592582628907, + 0.77142266494622, + 0.58130867351132, + -0.25881904510252 ) + TKFRAME_-43750_RELATIVE = 'IMAP_SPACECRAFT' + +\begintext + + Generic axis + + +Z axis + . + | + . + | + . + | + . + | + . + | + . + | + .~ ~ + .~ '` ^~ + .~ '` ^~ + .~ '` ^~ + .~ '` ^~ + +X axis ^~ + ^~ + ^~ + +Y axis + +End of FK file. \ No newline at end of file From ff6ce9215936fd28a38821d64283d14c7ca664af Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 20 Aug 2024 10:12:42 -0600 Subject: [PATCH 04/32] format test --- .../tests/pointing_frame/test_pointing_frame_handler.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py b/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py index 34c875ce3..d7017d8c7 100644 --- a/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py +++ b/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py @@ -55,7 +55,7 @@ def create_kernel_list(kernel_path): return kernels, ck_kernel -# @pytest.mark.xfail(reason="Will fail unless imap_spin.bc is in /test-data/spice/.") +@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_get_coverage(create_kernel_list): """Tests get_coverage function.""" kernels, ck_kernel = create_kernel_list @@ -67,7 +67,7 @@ def test_get_coverage(create_kernel_list): assert et_end == 802094467.184905 -# @pytest.mark.xfail(reason="Will fail unless imap_spin.bc is in /test-data/spice/.") +@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): """Tests create_pointing_frame function.""" monkeypatch.setenv("EFS_MOUNT_PATH", str(kernel_path)) @@ -93,7 +93,7 @@ def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): np.testing.assert_allclose(rotation_matrix_1, rotation_matrix_expected, atol=1e-4) -# @pytest.mark.xfail(reason="Will fail unless imap_spin.bc is in /test-data/spice/.") +@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_z_axis(create_kernel_list): """Tests Inertial z axis and provides visualization.""" kernels, ck_kernel = create_kernel_list From 49039f8da69efaa74bea12bbd37f6c24b7ef5606 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 20 Aug 2024 10:29:30 -0600 Subject: [PATCH 05/32] env --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 598c512e7..b7a21cde7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,11 +52,12 @@ ruff = {version="==0.2.1", optional=true} sphinx = {version="*", optional=true} sphinxcontrib-openapi = {version="^0.8.3", optional=true} mypy = {version="^1.10.1", optional=true} +matplotlib = {version="^3.7.1", optional=true} [tool.poetry.extras] dev = ["pre-commit", "ruff", "mypy"] doc = ["numpydoc", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-openapi"] -test = ["openpyxl", "pytest", "pytest-cov"] +test = ["openpyxl", "pytest", "pytest-cov", "matplotlib"] tools= ["openpyxl", "pandas"] [project.urls] From c7339b7b94226b6d66108eca0e947774be6bda10 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 20 Aug 2024 11:31:45 -0600 Subject: [PATCH 06/32] code cov update --- imap_processing/pointing_frame_handler.py | 8 +++--- .../test_pointing_frame_handler.py | 27 ++++++++++++++++--- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/imap_processing/pointing_frame_handler.py b/imap_processing/pointing_frame_handler.py index c10e76653..099ebbab8 100644 --- a/imap_processing/pointing_frame_handler.py +++ b/imap_processing/pointing_frame_handler.py @@ -49,10 +49,6 @@ def get_coverage(ck_kernel: str) -> tuple[float, float, np.ndarray]: et_times : numpy.ndarray Array of times between et_start and et_end. """ - # Each spin is 15 seconds. We want 10 quaternions per spin. - # duration / # samples (nominally 15/10 = 1.5 seconds) - step = 1.5 - # Get the spacecraft ID. # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool id_imap_spacecraft = spice.gipool("FRAME_IMAP_SPACECRAFT", 0, 1) @@ -64,7 +60,9 @@ def get_coverage(ck_kernel: str) -> tuple[float, float, np.ndarray]: cover = spice.ckcov(ck_kernel, int(id_imap_spacecraft), True, "SEGMENT", 0, "TDB") # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.wnfetd et_start, et_end = spice.wnfetd(cover, 0) - et_times = np.arange(et_start, et_end, step) + # Each spin is 15 seconds. We want 10 quaternions per spin. + # duration / # samples (nominally 15/10 = 1.5 seconds) + et_times = np.arange(et_start, et_end, 1.5) return et_start, et_end, et_times diff --git a/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py b/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py index d7017d8c7..fc90fa5e1 100644 --- a/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py +++ b/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py @@ -55,8 +55,8 @@ def create_kernel_list(kernel_path): return kernels, ck_kernel -@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") -def test_get_coverage(create_kernel_list): +@pytest.fixture() +def et_times(create_kernel_list): """Tests get_coverage function.""" kernels, ck_kernel = create_kernel_list @@ -66,8 +66,27 @@ def test_get_coverage(create_kernel_list): assert et_start == 802008069.184905 assert et_end == 802094467.184905 + return et_times + + +def test_create_rotation_matrix(et_times, kernel_path): + """Tests create_rotation_matrix function.""" + + kernels = [str(file) for file in kernel_path.iterdir()] + + with spice.KernelPool(kernels): + rotation_matrix, z_avg = create_rotation_matrix(et_times) + + rotation_matrix_expected = np.array( + [[0.0000, 0.0000, 1.0000], [0.9104, -0.4136, 0.0000], [0.4136, 0.9104, 0.0000]] + ) + z_avg_expected = np.array([0.4136, 0.9104, 0.0000]) + + np.testing.assert_allclose(z_avg, z_avg_expected, atol=1e-4) + np.testing.assert_allclose(rotation_matrix, rotation_matrix_expected, atol=1e-4) + -@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") +# @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): """Tests create_pointing_frame function.""" monkeypatch.setenv("EFS_MOUNT_PATH", str(kernel_path)) @@ -93,7 +112,7 @@ def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): np.testing.assert_allclose(rotation_matrix_1, rotation_matrix_expected, atol=1e-4) -@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") +# @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_z_axis(create_kernel_list): """Tests Inertial z axis and provides visualization.""" kernels, ck_kernel = create_kernel_list From 1aa2890f466a5f9ba5994abd42008e38850832bb Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 20 Aug 2024 11:45:18 -0600 Subject: [PATCH 07/32] code cov update --- imap_processing/pointing_frame_handler.py | 5 ++--- .../tests/pointing_frame/test_pointing_frame_handler.py | 5 +++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/imap_processing/pointing_frame_handler.py b/imap_processing/pointing_frame_handler.py index 099ebbab8..14030b5a1 100644 --- a/imap_processing/pointing_frame_handler.py +++ b/imap_processing/pointing_frame_handler.py @@ -97,11 +97,10 @@ def average_quaternions(et_times: np.ndarray) -> tuple[np.ndarray, list[np.ndarr z_eclip_time.append(body_rots[:, 2]) # Standardize the quaternion so that they may be compared. - if body_quat[0] < 0: - body_quat = -body_quat + body_quat = body_quat * np.sign(body_quat[0]) # Aggregate quaternions into a single matrix. - aggregate += np.outer(body_quat, body_quat) + aggregate += np.outer(np.abs(body_quat), body_quat) # Reference: "On Averaging Rotations" # Link: https://link.springer.com/content/pdf/10.1023/A:1011129215388.pdf diff --git a/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py b/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py index fc90fa5e1..31a9c892b 100644 --- a/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py +++ b/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py @@ -69,6 +69,7 @@ def et_times(create_kernel_list): return et_times +@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_create_rotation_matrix(et_times, kernel_path): """Tests create_rotation_matrix function.""" @@ -86,7 +87,7 @@ def test_create_rotation_matrix(et_times, kernel_path): np.testing.assert_allclose(rotation_matrix, rotation_matrix_expected, atol=1e-4) -# @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") +@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): """Tests create_pointing_frame function.""" monkeypatch.setenv("EFS_MOUNT_PATH", str(kernel_path)) @@ -112,7 +113,7 @@ def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): np.testing.assert_allclose(rotation_matrix_1, rotation_matrix_expected, atol=1e-4) -# @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") +@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_z_axis(create_kernel_list): """Tests Inertial z axis and provides visualization.""" kernels, ck_kernel = create_kernel_list From 804c3ac003531d684edc0f44fc5c9348848695c2 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 20 Aug 2024 13:40:42 -0600 Subject: [PATCH 08/32] code cov update --- imap_processing/pointing_frame_handler.py | 2 +- .../test_pointing_frame_handler.py | 24 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/imap_processing/pointing_frame_handler.py b/imap_processing/pointing_frame_handler.py index 14030b5a1..dd6444d4f 100644 --- a/imap_processing/pointing_frame_handler.py +++ b/imap_processing/pointing_frame_handler.py @@ -100,7 +100,7 @@ def average_quaternions(et_times: np.ndarray) -> tuple[np.ndarray, list[np.ndarr body_quat = body_quat * np.sign(body_quat[0]) # Aggregate quaternions into a single matrix. - aggregate += np.outer(np.abs(body_quat), body_quat) + aggregate += np.outer(body_quat, body_quat) # Reference: "On Averaging Rotations" # Link: https://link.springer.com/content/pdf/10.1023/A:1011129215388.pdf diff --git a/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py b/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py index 31a9c892b..8e089c62f 100644 --- a/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py +++ b/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py @@ -60,13 +60,35 @@ def et_times(create_kernel_list): """Tests get_coverage function.""" kernels, ck_kernel = create_kernel_list + with spice.KernelPool(kernels): + et_start, et_end, et_times = get_coverage(str(ck_kernel[0])) + + return et_times + + +@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") +def test_get_coverage(create_kernel_list): + """Tests get_coverage function.""" + kernels, ck_kernel = create_kernel_list + with spice.KernelPool(kernels): et_start, et_end, et_times = get_coverage(str(ck_kernel[0])) assert et_start == 802008069.184905 assert et_end == 802094467.184905 - return et_times + +@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") +def test_average_quaternions(et_times, create_kernel_list): + """Tests average_quaternions function.""" + + kernels, ck_kernel = create_kernel_list + with spice.KernelPool(kernels): + q_avg, z_eclip_time = average_quaternions(et_times) + + # Generated from MATLAB code results + q_avg_expected = np.array([-0.6838, 0.5480, -0.4469, -0.1802]) + np.testing.assert_allclose(q_avg, q_avg_expected, atol=1e-4) @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") From 6c3f13312cba253e0dad99beef7bdf565b22bafe Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 20 Aug 2024 13:50:26 -0600 Subject: [PATCH 09/32] update to poetrylock --- poetry.lock | 1214 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 849 insertions(+), 365 deletions(-) diff --git a/poetry.lock b/poetry.lock index 83c5479d1..d7d07d3f5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "accessible-pygments" @@ -31,32 +31,32 @@ files = [ [[package]] name = "attrs" -version = "23.2.0" +version = "24.2.0" description = "Classes Without Boilerplate" optional = true python-versions = ">=3.7" files = [ - {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, - {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, ] [package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] -tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "babel" -version = "2.15.0" +version = "2.16.0" description = "Internationalization utilities" optional = true python-versions = ">=3.8" files = [ - {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, - {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, + {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, + {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, ] [package.extras] @@ -248,13 +248,13 @@ tests = ["astropy", "hypothesis", "pytest (>=3.9)", "pytest-cov", "pytest-remote [[package]] name = "certifi" -version = "2024.6.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = true python-versions = ">=3.6" files = [ - {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, - {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] @@ -378,65 +378,148 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "contourpy" +version = "1.2.1" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = true +python-versions = ">=3.9" +files = [ + {file = "contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040"}, + {file = "contourpy-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b"}, + {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd"}, + {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619"}, + {file = "contourpy-1.2.1-cp310-cp310-win32.whl", hash = "sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8"}, + {file = "contourpy-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9"}, + {file = "contourpy-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5"}, + {file = "contourpy-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df"}, + {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205"}, + {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8"}, + {file = "contourpy-1.2.1-cp311-cp311-win32.whl", hash = "sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec"}, + {file = "contourpy-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922"}, + {file = "contourpy-1.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc"}, + {file = "contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b"}, + {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce"}, + {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4"}, + {file = "contourpy-1.2.1-cp312-cp312-win32.whl", hash = "sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f"}, + {file = "contourpy-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce"}, + {file = "contourpy-1.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b"}, + {file = "contourpy-1.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445"}, + {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02"}, + {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083"}, + {file = "contourpy-1.2.1-cp39-cp39-win32.whl", hash = "sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba"}, + {file = "contourpy-1.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f"}, + {file = "contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c"}, +] + +[package.dependencies] +numpy = ">=1.20" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.8.0)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] + [[package]] name = "coverage" -version = "7.5.4" +version = "7.6.1" description = "Code coverage measurement for Python" optional = true python-versions = ">=3.8" files = [ - {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, - {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, - {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, - {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, - {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, - {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, - {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, - {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, - {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, - {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, - {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, - {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, - {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, - {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, - {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, - {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, - {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, - {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, - {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, - {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, - {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, - {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, + {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, + {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, + {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, + {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, + {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, + {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, + {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, + {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, + {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, + {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, + {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, + {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, + {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, + {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, + {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, + {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, ] [package.dependencies] @@ -445,6 +528,21 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = true +python-versions = ">=3.8" +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + [[package]] name = "deepmerge" version = "1.1.1" @@ -491,13 +589,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.1" +version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = true python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, - {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] @@ -519,15 +617,80 @@ docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1 testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] typing = ["typing-extensions (>=4.8)"] +[[package]] +name = "fonttools" +version = "4.53.1" +description = "Tools to manipulate font files" +optional = true +python-versions = ">=3.8" +files = [ + {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, + {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, + {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, + {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, + {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, + {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, + {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, + {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, + {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, + {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, + {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, + {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, + {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "pycairo", "scipy"] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=15.1.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + [[package]] name = "identify" -version = "2.5.36" +version = "2.6.0" description = "File identification library for Python" optional = true python-versions = ">=3.8" files = [ - {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, - {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, + {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"}, + {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"}, ] [package.extras] @@ -557,12 +720,12 @@ files = [ [[package]] name = "imap-data-access" -version = "0.7.0" +version = "0.9.0" description = "IMAP SDC Data Access" optional = false python-versions = "*" files = [ - {file = "imap_data_access-0.7.0.tar.gz", hash = "sha256:f0db935949d048394fc554b308b1e4a1572a18acd41636462d37c309c7cb4c9d"}, + {file = "imap_data_access-0.9.0.tar.gz", hash = "sha256:997084118c85455d1c977d5640a8654717a1f8adf39eaeccfc3e124b5efd3c4f"}, ] [package.extras] @@ -571,13 +734,13 @@ test = ["pytest", "pytest-cov"] [[package]] name = "importlib-metadata" -version = "8.0.0" +version = "8.4.0" description = "Read metadata from Python packages" optional = true python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, - {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, + {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"}, + {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"}, ] [package.dependencies] @@ -588,6 +751,24 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke perf = ["ipython"] test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +[[package]] +name = "importlib-resources" +version = "6.4.3" +description = "Read resources from Python packages" +optional = true +python-versions = ">=3.8" +files = [ + {file = "importlib_resources-6.4.3-py3-none-any.whl", hash = "sha256:2d6dfe3b9e055f72495c2085890837fc8c758984e209115c8792bddcb762cd93"}, + {file = "importlib_resources-6.4.3.tar.gz", hash = "sha256:4a202b9b9d38563b46da59221d77bb73862ab5d79d461307bcb826d725448b98"}, +] + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -618,13 +799,13 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsonschema" -version = "4.22.0" +version = "4.23.0" description = "An implementation of JSON Schema validation for Python" optional = true python-versions = ">=3.8" files = [ - {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, - {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, ] [package.dependencies] @@ -635,7 +816,7 @@ rpds-py = ">=0.7.1" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] [[package]] name = "jsonschema-specifications" @@ -651,6 +832,119 @@ files = [ [package.dependencies] referencing = ">=0.31.0" +[[package]] +name = "kiwisolver" +version = "1.4.5" +description = "A fast implementation of the Cassowary constraint solver" +optional = true +python-versions = ">=3.7" +files = [ + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, + {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, +] + [[package]] name = "markupsafe" version = "2.1.5" @@ -720,6 +1014,70 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "matplotlib" +version = "3.9.2" +description = "Python plotting package" +optional = true +python-versions = ">=3.9" +files = [ + {file = "matplotlib-3.9.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9d78bbc0cbc891ad55b4f39a48c22182e9bdaea7fc0e5dbd364f49f729ca1bbb"}, + {file = "matplotlib-3.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c375cc72229614632c87355366bdf2570c2dac01ac66b8ad048d2dabadf2d0d4"}, + {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d94ff717eb2bd0b58fe66380bd8b14ac35f48a98e7c6765117fe67fb7684e64"}, + {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab68d50c06938ef28681073327795c5db99bb4666214d2d5f880ed11aeaded66"}, + {file = "matplotlib-3.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:65aacf95b62272d568044531e41de26285d54aec8cb859031f511f84bd8b495a"}, + {file = "matplotlib-3.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:3fd595f34aa8a55b7fc8bf9ebea8aa665a84c82d275190a61118d33fbc82ccae"}, + {file = "matplotlib-3.9.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d8dd059447824eec055e829258ab092b56bb0579fc3164fa09c64f3acd478772"}, + {file = "matplotlib-3.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c797dac8bb9c7a3fd3382b16fe8f215b4cf0f22adccea36f1545a6d7be310b41"}, + {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d719465db13267bcef19ea8954a971db03b9f48b4647e3860e4bc8e6ed86610f"}, + {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8912ef7c2362f7193b5819d17dae8629b34a95c58603d781329712ada83f9447"}, + {file = "matplotlib-3.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7741f26a58a240f43bee74965c4882b6c93df3e7eb3de160126d8c8f53a6ae6e"}, + {file = "matplotlib-3.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:ae82a14dab96fbfad7965403c643cafe6515e386de723e498cf3eeb1e0b70cc7"}, + {file = "matplotlib-3.9.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ac43031375a65c3196bee99f6001e7fa5bdfb00ddf43379d3c0609bdca042df9"}, + {file = "matplotlib-3.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be0fc24a5e4531ae4d8e858a1a548c1fe33b176bb13eff7f9d0d38ce5112a27d"}, + {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf81de2926c2db243c9b2cbc3917619a0fc85796c6ba4e58f541df814bbf83c7"}, + {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ee45bc4245533111ced13f1f2cace1e7f89d1c793390392a80c139d6cf0e6c"}, + {file = "matplotlib-3.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:306c8dfc73239f0e72ac50e5a9cf19cc4e8e331dd0c54f5e69ca8758550f1e1e"}, + {file = "matplotlib-3.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:5413401594cfaff0052f9d8b1aafc6d305b4bd7c4331dccd18f561ff7e1d3bd3"}, + {file = "matplotlib-3.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:18128cc08f0d3cfff10b76baa2f296fc28c4607368a8402de61bb3f2eb33c7d9"}, + {file = "matplotlib-3.9.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4876d7d40219e8ae8bb70f9263bcbe5714415acfdf781086601211335e24f8aa"}, + {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d9f07a80deab4bb0b82858a9e9ad53d1382fd122be8cde11080f4e7dfedb38b"}, + {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7c0410f181a531ec4e93bbc27692f2c71a15c2da16766f5ba9761e7ae518413"}, + {file = "matplotlib-3.9.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:909645cce2dc28b735674ce0931a4ac94e12f5b13f6bb0b5a5e65e7cea2c192b"}, + {file = "matplotlib-3.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:f32c7410c7f246838a77d6d1eff0c0f87f3cb0e7c4247aebea71a6d5a68cab49"}, + {file = "matplotlib-3.9.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:37e51dd1c2db16ede9cfd7b5cabdfc818b2c6397c83f8b10e0e797501c963a03"}, + {file = "matplotlib-3.9.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b82c5045cebcecd8496a4d694d43f9cc84aeeb49fe2133e036b207abe73f4d30"}, + {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f053c40f94bc51bc03832a41b4f153d83f2062d88c72b5e79997072594e97e51"}, + {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbe196377a8248972f5cede786d4c5508ed5f5ca4a1e09b44bda889958b33f8c"}, + {file = "matplotlib-3.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5816b1e1fe8c192cbc013f8f3e3368ac56fbecf02fb41b8f8559303f24c5015e"}, + {file = "matplotlib-3.9.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:cef2a73d06601437be399908cf13aee74e86932a5ccc6ccdf173408ebc5f6bb2"}, + {file = "matplotlib-3.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e0830e188029c14e891fadd99702fd90d317df294c3298aad682739c5533721a"}, + {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ba9c1299c920964e8d3857ba27173b4dbb51ca4bab47ffc2c2ba0eb5e2cbc5"}, + {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cd93b91ab47a3616b4d3c42b52f8363b88ca021e340804c6ab2536344fad9ca"}, + {file = "matplotlib-3.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6d1ce5ed2aefcdce11904fc5bbea7d9c21fff3d5f543841edf3dea84451a09ea"}, + {file = "matplotlib-3.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:b2696efdc08648536efd4e1601b5fd491fd47f4db97a5fbfd175549a7365c1b2"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d52a3b618cb1cbb769ce2ee1dcdb333c3ab6e823944e9a2d36e37253815f9556"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:039082812cacd6c6bec8e17a9c1e6baca230d4116d522e81e1f63a74d01d2e21"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6758baae2ed64f2331d4fd19be38b7b4eae3ecec210049a26b6a4f3ae1c85dcc"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:050598c2b29e0b9832cde72bcf97627bf00262adbc4a54e2b856426bb2ef0697"}, + {file = "matplotlib-3.9.2.tar.gz", hash = "sha256:96ab43906269ca64a6366934106fa01534454a69e471b7bf3d79083981aaab92"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} +kiwisolver = ">=1.3.1" +numpy = ">=1.23" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + +[package.extras] +dev = ["meson-python (>=0.13.1)", "numpy (>=1.25)", "pybind11 (>=2.6)", "setuptools (>=64)", "setuptools_scm (>=7)"] + [[package]] name = "mistune" version = "3.0.2" @@ -733,44 +1091,44 @@ files = [ [[package]] name = "mypy" -version = "1.10.1" +version = "1.11.1" description = "Optional static typing for Python" optional = true python-versions = ">=3.8" files = [ - {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, - {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, - {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, - {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, - {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, - {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, - {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, - {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, - {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, - {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, - {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, - {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, - {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, - {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, - {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, - {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, - {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, - {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, - {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, - {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, - {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, - {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, - {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, - {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, - {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, - {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, - {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, + {file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"}, + {file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"}, + {file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"}, + {file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"}, + {file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"}, + {file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"}, + {file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"}, + {file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"}, + {file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"}, + {file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"}, + {file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"}, + {file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"}, + {file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"}, + {file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"}, + {file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"}, + {file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"}, + {file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"}, + {file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"}, + {file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"}, + {file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"}, + {file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"}, + {file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"}, + {file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"}, + {file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"}, + {file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"}, + {file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"}, + {file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"}, ] [package.dependencies] mypy-extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.1.0" +typing-extensions = ">=4.6.0" [package.extras] dmypy = ["psutil (>=4.0)"] @@ -802,58 +1160,67 @@ files = [ [[package]] name = "numpy" -version = "1.26.4" +version = "2.0.1" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.9" files = [ - {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, - {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, - {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, - {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, - {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, - {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, - {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, - {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, - {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, - {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, - {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, - {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, - {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, - {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, - {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, - {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, - {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, - {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, - {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, - {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, - {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, - {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, - {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, - {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, - {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, - {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, - {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, - {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, - {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, - {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, - {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, - {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, - {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, + {file = "numpy-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fbb536eac80e27a2793ffd787895242b7f18ef792563d742c2d673bfcb75134"}, + {file = "numpy-2.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:69ff563d43c69b1baba77af455dd0a839df8d25e8590e79c90fcbe1499ebde42"}, + {file = "numpy-2.0.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:1b902ce0e0a5bb7704556a217c4f63a7974f8f43e090aff03fcf262e0b135e02"}, + {file = "numpy-2.0.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:f1659887361a7151f89e79b276ed8dff3d75877df906328f14d8bb40bb4f5101"}, + {file = "numpy-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4658c398d65d1b25e1760de3157011a80375da861709abd7cef3bad65d6543f9"}, + {file = "numpy-2.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4127d4303b9ac9f94ca0441138acead39928938660ca58329fe156f84b9f3015"}, + {file = "numpy-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e5eeca8067ad04bc8a2a8731183d51d7cbaac66d86085d5f4766ee6bf19c7f87"}, + {file = "numpy-2.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9adbd9bb520c866e1bfd7e10e1880a1f7749f1f6e5017686a5fbb9b72cf69f82"}, + {file = "numpy-2.0.1-cp310-cp310-win32.whl", hash = "sha256:7b9853803278db3bdcc6cd5beca37815b133e9e77ff3d4733c247414e78eb8d1"}, + {file = "numpy-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:81b0893a39bc5b865b8bf89e9ad7807e16717f19868e9d234bdaf9b1f1393868"}, + {file = "numpy-2.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75b4e316c5902d8163ef9d423b1c3f2f6252226d1aa5cd8a0a03a7d01ffc6268"}, + {file = "numpy-2.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6e4eeb6eb2fced786e32e6d8df9e755ce5be920d17f7ce00bc38fcde8ccdbf9e"}, + {file = "numpy-2.0.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a1e01dcaab205fbece13c1410253a9eea1b1c9b61d237b6fa59bcc46e8e89343"}, + {file = "numpy-2.0.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a8fc2de81ad835d999113ddf87d1ea2b0f4704cbd947c948d2f5513deafe5a7b"}, + {file = "numpy-2.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a3d94942c331dd4e0e1147f7a8699a4aa47dffc11bf8a1523c12af8b2e91bbe"}, + {file = "numpy-2.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15eb4eca47d36ec3f78cde0a3a2ee24cf05ca7396ef808dda2c0ddad7c2bde67"}, + {file = "numpy-2.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b83e16a5511d1b1f8a88cbabb1a6f6a499f82c062a4251892d9ad5d609863fb7"}, + {file = "numpy-2.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f87fec1f9bc1efd23f4227becff04bd0e979e23ca50cc92ec88b38489db3b55"}, + {file = "numpy-2.0.1-cp311-cp311-win32.whl", hash = "sha256:36d3a9405fd7c511804dc56fc32974fa5533bdeb3cd1604d6b8ff1d292b819c4"}, + {file = "numpy-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:08458fbf403bff5e2b45f08eda195d4b0c9b35682311da5a5a0a0925b11b9bd8"}, + {file = "numpy-2.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6bf4e6f4a2a2e26655717a1983ef6324f2664d7011f6ef7482e8c0b3d51e82ac"}, + {file = "numpy-2.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6fddc5fe258d3328cd8e3d7d3e02234c5d70e01ebe377a6ab92adb14039cb4"}, + {file = "numpy-2.0.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:5daab361be6ddeb299a918a7c0864fa8618af66019138263247af405018b04e1"}, + {file = "numpy-2.0.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:ea2326a4dca88e4a274ba3a4405eb6c6467d3ffbd8c7d38632502eaae3820587"}, + {file = "numpy-2.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:529af13c5f4b7a932fb0e1911d3a75da204eff023ee5e0e79c1751564221a5c8"}, + {file = "numpy-2.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6790654cb13eab303d8402354fabd47472b24635700f631f041bd0b65e37298a"}, + {file = "numpy-2.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbab9fc9c391700e3e1287666dfd82d8666d10e69a6c4a09ab97574c0b7ee0a7"}, + {file = "numpy-2.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:99d0d92a5e3613c33a5f01db206a33f8fdf3d71f2912b0de1739894668b7a93b"}, + {file = "numpy-2.0.1-cp312-cp312-win32.whl", hash = "sha256:173a00b9995f73b79eb0191129f2455f1e34c203f559dd118636858cc452a1bf"}, + {file = "numpy-2.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:bb2124fdc6e62baae159ebcfa368708867eb56806804d005860b6007388df171"}, + {file = "numpy-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bfc085b28d62ff4009364e7ca34b80a9a080cbd97c2c0630bb5f7f770dae9414"}, + {file = "numpy-2.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8fae4ebbf95a179c1156fab0b142b74e4ba4204c87bde8d3d8b6f9c34c5825ef"}, + {file = "numpy-2.0.1-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:72dc22e9ec8f6eaa206deb1b1355eb2e253899d7347f5e2fae5f0af613741d06"}, + {file = "numpy-2.0.1-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:ec87f5f8aca726117a1c9b7083e7656a9d0d606eec7299cc067bb83d26f16e0c"}, + {file = "numpy-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f682ea61a88479d9498bf2091fdcd722b090724b08b31d63e022adc063bad59"}, + {file = "numpy-2.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8efc84f01c1cd7e34b3fb310183e72fcdf55293ee736d679b6d35b35d80bba26"}, + {file = "numpy-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3fdabe3e2a52bc4eff8dc7a5044342f8bd9f11ef0934fcd3289a788c0eb10018"}, + {file = "numpy-2.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:24a0e1befbfa14615b49ba9659d3d8818a0f4d8a1c5822af8696706fbda7310c"}, + {file = "numpy-2.0.1-cp39-cp39-win32.whl", hash = "sha256:f9cf5ea551aec449206954b075db819f52adc1638d46a6738253a712d553c7b4"}, + {file = "numpy-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:e9e81fa9017eaa416c056e5d9e71be93d05e2c3c2ab308d23307a8bc4443c368"}, + {file = "numpy-2.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:61728fba1e464f789b11deb78a57805c70b2ed02343560456190d0501ba37b0f"}, + {file = "numpy-2.0.1-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:12f5d865d60fb9734e60a60f1d5afa6d962d8d4467c120a1c0cda6eb2964437d"}, + {file = "numpy-2.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eacf3291e263d5a67d8c1a581a8ebbcfd6447204ef58828caf69a5e3e8c75990"}, + {file = "numpy-2.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2c3a346ae20cfd80b6cfd3e60dc179963ef2ea58da5ec074fd3d9e7a1e7ba97f"}, + {file = "numpy-2.0.1.tar.gz", hash = "sha256:485b87235796410c3519a699cfe1faab097e509e90ebb05dcd098db2ae87e7b3"}, ] [[package]] name = "numpydoc" -version = "1.7.0" +version = "1.8.0" description = "Sphinx extension to support docstrings in Numpy format" optional = true -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "numpydoc-1.7.0-py3-none-any.whl", hash = "sha256:5a56419d931310d79a06cfc2a126d1558700feeb9b4f3d8dcae1a8134be829c9"}, - {file = "numpydoc-1.7.0.tar.gz", hash = "sha256:866e5ae5b6509dcf873fc6381120f5c31acf13b135636c1a81d68c166a95f921"}, + {file = "numpydoc-1.8.0-py3-none-any.whl", hash = "sha256:72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541"}, + {file = "numpydoc-1.8.0.tar.gz", hash = "sha256:022390ab7464a44f8737f79f8b31ce1d3cfa4b4af79ccaa1aac5e8368db587fb"}, ] [package.dependencies] @@ -863,7 +1230,7 @@ tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} [package.extras] developer = ["pre-commit (>=3.3)", "tomli"] -doc = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pydata-sphinx-theme (>=0.13.3)", "sphinx (>=7)"] +doc = ["intersphinx-registry", "matplotlib (>=3.5)", "numpy (>=1.22)", "pydata-sphinx-theme (>=0.13.3)", "sphinx (>=7)"] test = ["matplotlib", "pytest", "pytest-cov"] [[package]] @@ -975,6 +1342,103 @@ files = [ {file = "picobox-4.0.0.tar.gz", hash = "sha256:114da1b5606b2f615e8b0eb68d04198ad9de75af5adbcf5b36fe4f664ab927b6"}, ] +[[package]] +name = "pillow" +version = "10.4.0" +description = "Python Imaging Library (Fork)" +optional = true +python-versions = ">=3.8" +files = [ + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] + [[package]] name = "platformdirs" version = "4.2.2" @@ -1008,13 +1472,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "3.7.1" +version = "3.8.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = true python-versions = ">=3.9" files = [ - {file = "pre_commit-3.7.1-py2.py3-none-any.whl", hash = "sha256:fae36fd1d7ad7d6a5a1c0b0d5adb2ed1a3bda5a21bf6c3e5372073d7a11cd4c5"}, - {file = "pre_commit-3.7.1.tar.gz", hash = "sha256:8ca3ad567bc78a4972a3f1a477e94a79d4597e8140a6e0b651c5e33899c3654a"}, + {file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"}, + {file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"}, ] [package.dependencies] @@ -1066,15 +1530,29 @@ files = [ [package.extras] windows-terminal = ["colorama (>=0.4.6)"] +[[package]] +name = "pyparsing" +version = "3.1.2" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = true +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, + {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + [[package]] name = "pytest" -version = "8.2.2" +version = "8.3.2" description = "pytest: simple powerful testing with Python" optional = true python-versions = ">=3.8" files = [ - {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, - {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, + {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, + {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, ] [package.dependencies] @@ -1082,7 +1560,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.5,<2.0" +pluggy = ">=1.5,<2" tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] @@ -1133,62 +1611,64 @@ files = [ [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] @@ -1229,110 +1709,114 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rpds-py" -version = "0.18.1" +version = "0.20.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = true python-versions = ">=3.8" files = [ - {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"}, - {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"}, - {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"}, - {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"}, - {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"}, - {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"}, - {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"}, - {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"}, - {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"}, - {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"}, - {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"}, - {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"}, - {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"}, - {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"}, - {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"}, - {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"}, - {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"}, - {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"}, - {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"}, - {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"}, - {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, + {file = "rpds_py-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2"}, + {file = "rpds_py-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94"}, + {file = "rpds_py-0.20.0-cp310-none-win32.whl", hash = "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee"}, + {file = "rpds_py-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58"}, + {file = "rpds_py-0.20.0-cp311-none-win32.whl", hash = "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0"}, + {file = "rpds_py-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174"}, + {file = "rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139"}, + {file = "rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57"}, + {file = "rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a"}, + {file = "rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a"}, + {file = "rpds_py-0.20.0-cp38-none-win32.whl", hash = "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5"}, + {file = "rpds_py-0.20.0-cp38-none-win_amd64.whl", hash = "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b"}, + {file = "rpds_py-0.20.0-cp39-none-win32.whl", hash = "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7"}, + {file = "rpds_py-0.20.0-cp39-none-win_amd64.whl", hash = "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8"}, + {file = "rpds_py-0.20.0.tar.gz", hash = "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121"}, ] [[package]] @@ -1385,13 +1869,13 @@ files = [ [[package]] name = "soupsieve" -version = "2.5" +version = "2.6" description = "A modern CSS selector implementation for Beautiful Soup." optional = true python-versions = ">=3.8" files = [ - {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, - {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, + {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, + {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, ] [[package]] @@ -1410,27 +1894,27 @@ bitstring = ">=4.0.1" [[package]] name = "sphinx" -version = "7.3.7" +version = "7.4.7" description = "Python documentation generator" optional = true python-versions = ">=3.9" files = [ - {file = "sphinx-7.3.7-py3-none-any.whl", hash = "sha256:413f75440be4cacf328f580b4274ada4565fb2187d696a84970c23f77b64d8c3"}, - {file = "sphinx-7.3.7.tar.gz", hash = "sha256:a4a7db75ed37531c05002d56ed6948d4c42f473a36f46e1382b0bd76ca9627bc"}, + {file = "sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239"}, + {file = "sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe"}, ] [package.dependencies] alabaster = ">=0.7.14,<0.8.0" -babel = ">=2.9" -colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.18.1,<0.22" +babel = ">=2.13" +colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} +docutils = ">=0.20,<0.22" imagesize = ">=1.3" -importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} -Jinja2 = ">=3.0" -packaging = ">=21.0" -Pygments = ">=2.14" -requests = ">=2.25.0" -snowballstemmer = ">=2.0" +importlib-metadata = {version = ">=6.0", markers = "python_version < \"3.10\""} +Jinja2 = ">=3.1" +packaging = ">=23.0" +Pygments = ">=2.17" +requests = ">=2.30.0" +snowballstemmer = ">=2.2" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" sphinxcontrib-htmlhelp = ">=2.0.0" @@ -1441,22 +1925,22 @@ tomli = {version = ">=2", markers = "python_version < \"3.11\""} [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["flake8 (>=3.5.0)", "importlib_metadata", "mypy (==1.9.0)", "pytest (>=6.0)", "ruff (==0.3.7)", "sphinx-lint", "tomli", "types-docutils", "types-requests"] -test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=6.0)", "setuptools (>=67.0)"] +lint = ["flake8 (>=6.0)", "importlib-metadata (>=6.0)", "mypy (==1.10.1)", "pytest (>=6.0)", "ruff (==0.5.2)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-docutils (==0.21.0.20240711)", "types-requests (>=2.30.0)"] +test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"] [[package]] name = "sphinx-mdinclude" -version = "0.6.1" +version = "0.6.2" description = "Markdown extension for Sphinx" optional = true python-versions = ">=3.8" files = [ - {file = "sphinx_mdinclude-0.6.1-py3-none-any.whl", hash = "sha256:d96cb01b8ab23dc8e5e3932c8fbc91d402e7e708aa5ba8d63a8e627d00275ae6"}, - {file = "sphinx_mdinclude-0.6.1.tar.gz", hash = "sha256:ece3d812e2d559b4e7e47f67b6a87b0e2a689b6b2f5114795c8ed47ffb39c169"}, + {file = "sphinx_mdinclude-0.6.2-py3-none-any.whl", hash = "sha256:648e78edb067c0e4bffc22943278d49d54a0714494743592032fa3ad82a86984"}, + {file = "sphinx_mdinclude-0.6.2.tar.gz", hash = "sha256:447462e82cb8be61404a2204227f920769eb923d2f57608e3325f3bb88286b4c"}, ] [package.dependencies] -docutils = ">=0.16,<1.0" +docutils = ">=0.19,<1.0" mistune = ">=3.0,<4.0" pygments = ">=2.8" sphinx = ">=6" @@ -1466,49 +1950,49 @@ dev = ["attribution (==1.7.1)", "black (==24.4.2)", "coverage (==7.5.1)", "docut [[package]] name = "sphinxcontrib-applehelp" -version = "1.0.8" +version = "2.0.0" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4"}, - {file = "sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619"}, + {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, + {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-devhelp" -version = "1.0.6" +version = "2.0.0" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f"}, - {file = "sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3"}, + {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, + {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" -version = "2.0.5" +version = "2.1.0" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_htmlhelp-2.0.5-py3-none-any.whl", hash = "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04"}, - {file = "sphinxcontrib_htmlhelp-2.0.5.tar.gz", hash = "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015"}, + {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, + {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["html5lib", "pytest"] @@ -1563,33 +2047,33 @@ sphinxcontrib-httpdomain = ">=1.5.0" [[package]] name = "sphinxcontrib-qthelp" -version = "1.0.7" +version = "2.0.0" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_qthelp-1.0.7-py3-none-any.whl", hash = "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182"}, - {file = "sphinxcontrib_qthelp-1.0.7.tar.gz", hash = "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6"}, + {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, + {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] -test = ["pytest"] +test = ["defusedxml (>=0.7.1)", "pytest"] [[package]] name = "sphinxcontrib-serializinghtml" -version = "1.1.10" +version = "2.0.0" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7"}, - {file = "sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f"}, + {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, + {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, ] [package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] @@ -1701,13 +2185,13 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess [[package]] name = "xarray" -version = "2024.6.0" +version = "2024.7.0" description = "N-D labeled arrays and datasets in Python" optional = false python-versions = ">=3.9" files = [ - {file = "xarray-2024.6.0-py3-none-any.whl", hash = "sha256:721a7394e8ec3d592b2d8ebe21eed074ac077dc1bb1bd777ce00e41700b4866c"}, - {file = "xarray-2024.6.0.tar.gz", hash = "sha256:0b91e0bc4dc0296947947640fe31ec6e867ce258d2f7cbc10bedf4a6d68340c7"}, + {file = "xarray-2024.7.0-py3-none-any.whl", hash = "sha256:1b0fd51ec408474aa1f4a355d75c00cc1c02bd425d97b2c2e551fd21810e7f64"}, + {file = "xarray-2024.7.0.tar.gz", hash = "sha256:4cae512d121a8522d41e66d942fb06c526bc1fd32c2c181d5fe62fe65b671638"}, ] [package.dependencies] @@ -1725,13 +2209,13 @@ viz = ["matplotlib", "nc-time-axis", "seaborn"] [[package]] name = "zipp" -version = "3.19.2" +version = "3.20.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = true python-versions = ">=3.8" files = [ - {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, - {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, + {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, + {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, ] [package.extras] @@ -1741,10 +2225,10 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [extras] dev = ["mypy", "pre-commit", "ruff"] doc = ["numpydoc", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-openapi"] -test = ["openpyxl", "pytest", "pytest-cov"] +test = ["matplotlib", "openpyxl", "pytest", "pytest-cov"] tools = ["openpyxl", "pandas"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<4" -content-hash = "f750033025b765826c827adb1142fd59444e13a985755c2a6efc3a207348a959" +content-hash = "59a44fb08c81d71d3ab8e0ae21d87cc1a6db18386e16eae69146f821bcc43607" From 93fe87b569bddf7753e5e9f72ab7d678b5fb6d15 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 20 Aug 2024 14:42:02 -0600 Subject: [PATCH 10/32] pr response --- .../{ => spice}/pointing_frame_handler.py | 16 +- .../tests/pointing_frame/__init__.py | 0 .../test_data/imap_sclk_0000.tsc | 147 ------------------ .../test_data/imap_science_0001.tf | 0 .../test_data/imap_wkcp.tf | 0 .../test_pointing_frame_handler.py | 35 ++--- 6 files changed, 28 insertions(+), 170 deletions(-) rename imap_processing/{ => spice}/pointing_frame_handler.py (92%) delete mode 100644 imap_processing/tests/pointing_frame/__init__.py delete mode 100644 imap_processing/tests/pointing_frame/test_data/imap_sclk_0000.tsc rename imap_processing/tests/{pointing_frame => spice}/test_data/imap_science_0001.tf (100%) rename imap_processing/tests/{pointing_frame => spice}/test_data/imap_wkcp.tf (100%) rename imap_processing/tests/{pointing_frame => spice}/test_pointing_frame_handler.py (85%) diff --git a/imap_processing/pointing_frame_handler.py b/imap_processing/spice/pointing_frame_handler.py similarity index 92% rename from imap_processing/pointing_frame_handler.py rename to imap_processing/spice/pointing_frame_handler.py index dd6444d4f..111ee673c 100644 --- a/imap_processing/pointing_frame_handler.py +++ b/imap_processing/spice/pointing_frame_handler.py @@ -7,9 +7,8 @@ 1. imap_science_0001.tf - pointing frame kernel 2. imap_sclk_0000.tsc - spacecraft clock kernel 3. imap_wkcp.tf - spacecraft frame kernel -4. de430.bsp - standard SPICE planetary ephemeris kernel -5. naif0012.tls - standard NAIF leapsecond kernel -6. imap_spin.bc - test attitude kernel available at: +4. naif0012.tls - standard NAIF leapsecond kernel +5. imap_spin.bc - test attitude kernel available at: https://lasp.colorado.edu/galaxy/display/IMAP/Data These need to be placed in tests/pointing_frame/test_data. @@ -31,7 +30,7 @@ # TODO : Add multiple pointings to the pointing frame. -def get_coverage(ck_kernel: str) -> tuple[float, float, np.ndarray]: +def get_et_times(ck_kernel: str) -> tuple[float, float, np.ndarray]: """ Create the pointing frame. @@ -87,6 +86,13 @@ def average_quaternions(et_times: np.ndarray) -> tuple[np.ndarray, list[np.ndarr aggregate = np.zeros((4, 4)) for tdb in et_times: + # we use a quick and dirty method here for grabbing the quaternions + # from the attitude kernel. Depending on how well the kernel input + # data is built and sampled, there may or may not be aliasing with this + # approach. If it turns out that we need to pull the quaternions + # directly from the CK there are several routines that exist to do this + # but it's not straight forward. We'll revisit this if needed. + # Rotation matrix from IMAP spacecraft frame to ECLIPJ2000. # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.pxform body_rots = spice.pxform("IMAP_SPACECRAFT", "ECLIPJ2000", tdb) @@ -175,7 +181,7 @@ def create_pointing_frame() -> Path: # Furnish the kernels. with spice.KernelPool(kernels): # Get timerange for the pointing frame kernel. - et_start, et_end, et_times = get_coverage(str(ck_kernel[0])) + et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) # Create a rotation matrix rotation_matrix, _ = create_rotation_matrix(et_times) diff --git a/imap_processing/tests/pointing_frame/__init__.py b/imap_processing/tests/pointing_frame/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/imap_processing/tests/pointing_frame/test_data/imap_sclk_0000.tsc b/imap_processing/tests/pointing_frame/test_data/imap_sclk_0000.tsc deleted file mode 100644 index c52514a3c..000000000 --- a/imap_processing/tests/pointing_frame/test_data/imap_sclk_0000.tsc +++ /dev/null @@ -1,147 +0,0 @@ -\begintext - -FILENAME = "imap_0000.tsc" -CREATION_DATE = "2-October-2018" - - -IMAP Spacecraft Clock Kernel (SCLK) -=========================================================================== - - This file is a SPICE spacecraft clock (SCLK) kernel containing - information required for time conversions involving the on-board - IMAP spacecraft clock. - -Version --------------------------------------------------------- - - IMAP SCLK Kernel Version: - - IMAP Version 0.0 - April 12, 2023 -- Ian W. Murphy - The initial IMAP spice kernel. - This file was created by using DART initial kernel and - modifying the spacecraft ID. - - -Usage --------------------------------------------------------- - - This file is used by the SPICE system as follows: programs that - make use of this SCLK kernel must 'load' the kernel, normally - during program initialization. Loading the kernel associates - the data items with their names in a data structure called the - 'kernel pool'. The SPICELIB routine FURNSH loads text kernel - files, such as this one, into the pool as shown below: - - FORTRAN: - - CALL FURNSH ( SCLK_kernel_name ) - - C: - - furnsh_c ( SCLK_kernel_name ); - - Once loaded, the SCLK time conversion routines will be able to - access the necessary data located in this kernel for their - designed purposes. - -References --------------------------------------------------------- - - 1. "SCLK Required Reading" - -Inquiries --------------------------------------------------------- - - If you have any questions regarding this file or its usage, - contact: - - Scott Turner - (443)778-1693 - Scott.Turner@jhuapl.edu - -Kernel Data --------------------------------------------------------- - - The first block of keyword equals value assignments define the - type, parallel time system, and format of the spacecraft clock. - These fields are invariant from SCLK kernel update to SCLK - kernel update. - - The IMAP spacecraft clock is represented by the SPICE - type 1 SCLK kernel. It uses TDT, Terrestrial Dynamical Time, - as its parallel time system. - -\begindata - -SCLK_KERNEL_ID = ( @2009-07-09T12:20:32 ) -SCLK_DATA_TYPE_43 = ( 1 ) -SCLK_DATA_TYPE_43000 = ( 1 ) -SCLK01_TIME_SYSTEM_43 = ( 2 ) - -\begintext - - In a particular partition of the IMAP spacecraft clock, - the clock read-out consists of two separate stages: - - 1/18424652:24251 - - The first stage, a 32 bit field, represents the spacecraft - clock seconds count. The second, a 16 bit field, represents - counts of 20 microsecond increments of the spacecraft clock. - - The following keywords and their values establish this structure: - -\begindata - -SCLK01_N_FIELDS_43 = ( 2 ) -SCLK01_MODULI_43 = ( 4294967296 50000 ) -SCLK01_OFFSETS_43 = ( 0 0 ) -SCLK01_OUTPUT_DELIM_43 = ( 2 ) - - -\begintext - - This concludes the invariant portion of the SCLK kernel data. The - remaining sections of the kernel may require updates as the clock - correlation coefficients evolve in time. The first section below - establishes the clock partitions. The data in this section consists - of two parallel arrays, which denote the start and end values in - ticks of each partition of the spacecraft clock. - - SPICE utilizes these two arrays to map from spacecraft clock ticks, - determined with the usual modulo arithmetic, to encoded SCLK--the - internal, monotonically increasing sequence used to tag various - data sources with spacecraft clock. - -\begindata - -SCLK_PARTITION_START_43 = ( 0.00000000000000e+00 ) - -SCLK_PARTITION_END_43 = ( 2.14748364799999e+14 ) - -\begintext - - The remaining section of the SCLK kernel defines the clock correlation - coefficients. Each line contains a 'coefficient triple': - - Encoded SCLK at which Rate is introduced. - Corresponding TDT Epoch at which Rate is introduced. - Rate in TDT (seconds) / most significant clock count (~seconds). - - SPICE uses linear extrapolation to convert between the parallel time - system and encoded SCLK. The triples are stored in the array defined - below. - - The first time triplet below was entered manually and represents the - approximate time (in TDT) at which MET = zero. The current plan for - IMAP is that the given epoch will be used for both Observatory I&T - and launch. Note that the conversion from UTC to TDT used 34 leap - seconds. - -\begindata - -SCLK01_COEFFICIENTS_43 = ( - - 0 @01-JAN-2010-00:01:06.184000 1.00000000000 - -) diff --git a/imap_processing/tests/pointing_frame/test_data/imap_science_0001.tf b/imap_processing/tests/spice/test_data/imap_science_0001.tf similarity index 100% rename from imap_processing/tests/pointing_frame/test_data/imap_science_0001.tf rename to imap_processing/tests/spice/test_data/imap_science_0001.tf diff --git a/imap_processing/tests/pointing_frame/test_data/imap_wkcp.tf b/imap_processing/tests/spice/test_data/imap_wkcp.tf similarity index 100% rename from imap_processing/tests/pointing_frame/test_data/imap_wkcp.tf rename to imap_processing/tests/spice/test_data/imap_wkcp.tf diff --git a/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py b/imap_processing/tests/spice/test_pointing_frame_handler.py similarity index 85% rename from imap_processing/tests/pointing_frame/test_pointing_frame_handler.py rename to imap_processing/tests/spice/test_pointing_frame_handler.py index 8e089c62f..d986fd4a9 100644 --- a/imap_processing/tests/pointing_frame/test_pointing_frame_handler.py +++ b/imap_processing/tests/spice/test_pointing_frame_handler.py @@ -9,11 +9,11 @@ import pytest import spiceypy as spice -from imap_processing.pointing_frame_handler import ( +from imap_processing.spice.pointing_frame_handler import ( average_quaternions, create_pointing_frame, create_rotation_matrix, - get_coverage, + get_et_times, ) @@ -24,12 +24,11 @@ def kernel_path(tmp_path): test_dir = ( Path(sys.modules[__name__.split(".")[0]].__file__).parent / "tests" - / "pointing_frame" + / "spice" / "test_data" ) kernels = [ - "de430.bsp", "naif0012.tls", "imap_science_0001.tf", "imap_sclk_0000.tsc", @@ -57,25 +56,26 @@ def create_kernel_list(kernel_path): @pytest.fixture() def et_times(create_kernel_list): - """Tests get_coverage function.""" + """Tests get_et_times function.""" kernels, ck_kernel = create_kernel_list with spice.KernelPool(kernels): - et_start, et_end, et_times = get_coverage(str(ck_kernel[0])) + et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) return et_times @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") -def test_get_coverage(create_kernel_list): - """Tests get_coverage function.""" +def test_get_et_times(create_kernel_list): + """Tests get_et_times function.""" kernels, ck_kernel = create_kernel_list with spice.KernelPool(kernels): - et_start, et_end, et_times = get_coverage(str(ck_kernel[0])) + et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) assert et_start == 802008069.184905 assert et_end == 802094467.184905 + assert len(et_times) == 57599 @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") @@ -89,6 +89,7 @@ def test_average_quaternions(et_times, create_kernel_list): # Generated from MATLAB code results q_avg_expected = np.array([-0.6838, 0.5480, -0.4469, -0.1802]) np.testing.assert_allclose(q_avg, q_avg_expected, atol=1e-4) + assert len(z_eclip_time) == 57599 @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") @@ -120,7 +121,7 @@ def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): kernels = [str(file) for file in kernel_path.iterdir()] with spice.KernelPool(kernels): - et_start, et_end, et_times = get_coverage(str(ck_kernel[0])) + et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) rotation_matrix_1 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 100) rotation_matrix_2 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 1000) @@ -134,22 +135,20 @@ def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): ) np.testing.assert_allclose(rotation_matrix_1, rotation_matrix_expected, atol=1e-4) + # Verify imap_dps.bc has been created. + assert (kernel_path / "imap_dps.bc").exists() -@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") -def test_z_axis(create_kernel_list): + +@pytest.mark.skip(reason="Plotting only") +def test_declination_plot(create_kernel_list, et_times): """Tests Inertial z axis and provides visualization.""" kernels, ck_kernel = create_kernel_list with spice.KernelPool(kernels): - et_start, et_end, et_times = get_coverage(str(ck_kernel[0])) - # Converts rectangular coordinates to spherical coordinates. q_avg, z_eclip_time = average_quaternions(et_times) - z_avg_expected = spice.q2m(list(q_avg))[:, 2] _, z_avg = create_rotation_matrix(et_times) - assert np.array_equal(z_avg, z_avg_expected) - # Create visualization declination_list = [] for time in z_eclip_time: @@ -169,7 +168,7 @@ def test_z_axis(create_kernel_list): np.full(len(et_times), avg_declination * 180 / np.pi), "-r", linewidth=2, - label="mean z-axis for pointing frame", + label="mean declination for pointing frame", ) plt.xlabel("Ephemeris Time") plt.ylabel("Spacecraft Spin Axis Declination") From 1f1bb35b6484b3f495ca71158a06df058331b972 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 20 Aug 2024 16:40:43 -0600 Subject: [PATCH 11/32] change ck --- imap_processing/spice/pointing_frame_handler.py | 3 +++ .../tests/spice/test_pointing_frame_handler.py | 16 +++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/imap_processing/spice/pointing_frame_handler.py b/imap_processing/spice/pointing_frame_handler.py index 111ee673c..89e784759 100644 --- a/imap_processing/spice/pointing_frame_handler.py +++ b/imap_processing/spice/pointing_frame_handler.py @@ -61,6 +61,9 @@ def get_et_times(ck_kernel: str) -> tuple[float, float, np.ndarray]: et_start, et_end = spice.wnfetd(cover, 0) # Each spin is 15 seconds. We want 10 quaternions per spin. # duration / # samples (nominally 15/10 = 1.5 seconds) + + et_start = 802008069.184905 + et_end = 802094467.184905 et_times = np.arange(et_start, et_end, 1.5) return et_start, et_end, et_times diff --git a/imap_processing/tests/spice/test_pointing_frame_handler.py b/imap_processing/tests/spice/test_pointing_frame_handler.py index d986fd4a9..a59958836 100644 --- a/imap_processing/tests/spice/test_pointing_frame_handler.py +++ b/imap_processing/tests/spice/test_pointing_frame_handler.py @@ -33,7 +33,7 @@ def kernel_path(tmp_path): "imap_science_0001.tf", "imap_sclk_0000.tsc", "imap_wkcp.tf", - "imap_spin.bc", + "IMAP_spacecraft_attitude.bc", ] for file in test_dir.iterdir(): @@ -48,7 +48,9 @@ def create_kernel_list(kernel_path): """Create kernel lists.""" kernels = [str(file) for file in kernel_path.iterdir()] ck_kernel = [ - str(file) for file in kernel_path.iterdir() if file.name == "imap_spin.bc" + str(file) + for file in kernel_path.iterdir() + if file.name == "IMAP_spacecraft_attitude.bc" ] return kernels, ck_kernel @@ -65,7 +67,7 @@ def et_times(create_kernel_list): return et_times -@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") +# @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_get_et_times(create_kernel_list): """Tests get_et_times function.""" kernels, ck_kernel = create_kernel_list @@ -78,7 +80,7 @@ def test_get_et_times(create_kernel_list): assert len(et_times) == 57599 -@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") +# @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_average_quaternions(et_times, create_kernel_list): """Tests average_quaternions function.""" @@ -92,7 +94,7 @@ def test_average_quaternions(et_times, create_kernel_list): assert len(z_eclip_time) == 57599 -@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") +# @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_create_rotation_matrix(et_times, kernel_path): """Tests create_rotation_matrix function.""" @@ -110,7 +112,7 @@ def test_create_rotation_matrix(et_times, kernel_path): np.testing.assert_allclose(rotation_matrix, rotation_matrix_expected, atol=1e-4) -@pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") +# @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): """Tests create_pointing_frame function.""" monkeypatch.setenv("EFS_MOUNT_PATH", str(kernel_path)) @@ -139,7 +141,7 @@ def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): assert (kernel_path / "imap_dps.bc").exists() -@pytest.mark.skip(reason="Plotting only") +# @pytest.mark.skip(reason="Plotting only") def test_declination_plot(create_kernel_list, et_times): """Tests Inertial z axis and provides visualization.""" kernels, ck_kernel = create_kernel_list From bdf51e30b53e37daebef302c3151b415e5cce326 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Wed, 21 Aug 2024 10:06:35 -0600 Subject: [PATCH 12/32] pr response --- .../spice/pointing_frame_handler.py | 28 ++++----- .../spice/test_pointing_frame_handler.py | 63 ++++++++++--------- poetry.lock | 7 ++- pyproject.toml | 3 +- 4 files changed, 52 insertions(+), 49 deletions(-) diff --git a/imap_processing/spice/pointing_frame_handler.py b/imap_processing/spice/pointing_frame_handler.py index 89e784759..90a01666b 100644 --- a/imap_processing/spice/pointing_frame_handler.py +++ b/imap_processing/spice/pointing_frame_handler.py @@ -23,6 +23,7 @@ import numpy as np import spiceypy as spice +from numpy.typing import NDArray logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) @@ -59,17 +60,14 @@ def get_et_times(ck_kernel: str) -> tuple[float, float, np.ndarray]: cover = spice.ckcov(ck_kernel, int(id_imap_spacecraft), True, "SEGMENT", 0, "TDB") # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.wnfetd et_start, et_end = spice.wnfetd(cover, 0) - # Each spin is 15 seconds. We want 10 quaternions per spin. - # duration / # samples (nominally 15/10 = 1.5 seconds) - - et_start = 802008069.184905 - et_end = 802094467.184905 - et_times = np.arange(et_start, et_end, 1.5) + # Assumes a pointing is ~ 1 day. + # 1 spin/15 seconds * 86400 seconds/pointing * 10 quaternions / spin + et_times = np.linspace(et_start, et_end, 57600) return et_start, et_end, et_times -def average_quaternions(et_times: np.ndarray) -> tuple[np.ndarray, list[np.ndarray]]: +def average_quaternions(et_times: np.ndarray) -> NDArray: """ Average the quaternions. @@ -82,8 +80,6 @@ def average_quaternions(et_times: np.ndarray) -> tuple[np.ndarray, list[np.ndarr ------- q_avg : np.ndarray Average quaternion. - z_eclip_time : list - Z-axis of the ECLIPJ2000 frame. Used for plotting. """ z_eclip_time = [] aggregate = np.zeros((4, 4)) @@ -128,10 +124,10 @@ def average_quaternions(et_times: np.ndarray) -> tuple[np.ndarray, list[np.ndarr # q1, q2, q3: The vector part of the quaternion. q_avg = eigvecs[:, np.argmax(eigvals)] - return q_avg, z_eclip_time + return q_avg -def create_rotation_matrix(et_times: np.ndarray) -> tuple[np.ndarray, np.ndarray]: +def create_rotation_matrix(et_times: np.ndarray) -> NDArray: """ Create a rotation matrix. @@ -144,11 +140,9 @@ def create_rotation_matrix(et_times: np.ndarray) -> tuple[np.ndarray, np.ndarray ------- rotation_matrix : np.ndarray Rotation matrix. - z_avg : np.ndarray - Inertial z axis. Used for plotting. """ # Averaged quaternions. - q_avg, _ = average_quaternions(et_times) + q_avg = average_quaternions(et_times) # Converts the averaged quaternion (q_avg) into a rotation matrix # and get inertial z axis. @@ -160,9 +154,9 @@ def create_rotation_matrix(et_times: np.ndarray) -> tuple[np.ndarray, np.ndarray x_avg = np.cross(y_avg, z_avg) # Construct the rotation matrix from x_avg, y_avg, z_avg - rotation_matrix = np.array([x_avg, y_avg, z_avg]) + rotation_matrix = np.asarray([x_avg, y_avg, z_avg]) - return rotation_matrix, z_avg + return rotation_matrix def create_pointing_frame() -> Path: @@ -186,7 +180,7 @@ def create_pointing_frame() -> Path: # Get timerange for the pointing frame kernel. et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) # Create a rotation matrix - rotation_matrix, _ = create_rotation_matrix(et_times) + rotation_matrix = create_rotation_matrix(et_times) # Convert the rotation matrix to a quaternion. # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.m2q diff --git a/imap_processing/tests/spice/test_pointing_frame_handler.py b/imap_processing/tests/spice/test_pointing_frame_handler.py index a59958836..949a2c140 100644 --- a/imap_processing/tests/spice/test_pointing_frame_handler.py +++ b/imap_processing/tests/spice/test_pointing_frame_handler.py @@ -33,7 +33,7 @@ def kernel_path(tmp_path): "imap_science_0001.tf", "imap_sclk_0000.tsc", "imap_wkcp.tf", - "IMAP_spacecraft_attitude.bc", + "imap_spin.bc", ] for file in test_dir.iterdir(): @@ -44,22 +44,26 @@ def kernel_path(tmp_path): @pytest.fixture() -def create_kernel_list(kernel_path): - """Create kernel lists.""" +def kernels(kernel_path): + """Create kernel list.""" kernels = [str(file) for file in kernel_path.iterdir()] + + return kernels + + +@pytest.fixture() +def ck_kernel(kernel_path): + """Create ck kernel.""" ck_kernel = [ - str(file) - for file in kernel_path.iterdir() - if file.name == "IMAP_spacecraft_attitude.bc" + str(file) for file in kernel_path.iterdir() if file.name == "imap_spin.bc" ] - return kernels, ck_kernel + return ck_kernel @pytest.fixture() -def et_times(create_kernel_list): +def et_times(ck_kernel, kernels): """Tests get_et_times function.""" - kernels, ck_kernel = create_kernel_list with spice.KernelPool(kernels): et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) @@ -68,40 +72,37 @@ def et_times(create_kernel_list): # @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") -def test_get_et_times(create_kernel_list): +def test_get_et_times(kernels, ck_kernel): """Tests get_et_times function.""" - kernels, ck_kernel = create_kernel_list with spice.KernelPool(kernels): et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) assert et_start == 802008069.184905 assert et_end == 802094467.184905 - assert len(et_times) == 57599 + assert len(et_times) == 57600 # @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") -def test_average_quaternions(et_times, create_kernel_list): +def test_average_quaternions(et_times, kernels): """Tests average_quaternions function.""" - kernels, ck_kernel = create_kernel_list with spice.KernelPool(kernels): - q_avg, z_eclip_time = average_quaternions(et_times) + q_avg = average_quaternions(et_times) # Generated from MATLAB code results q_avg_expected = np.array([-0.6838, 0.5480, -0.4469, -0.1802]) - np.testing.assert_allclose(q_avg, q_avg_expected, atol=1e-4) - assert len(z_eclip_time) == 57599 + np.testing.assert_allclose(q_avg, q_avg_expected, atol=1e-1) # @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") -def test_create_rotation_matrix(et_times, kernel_path): +def test_create_rotation_matrix(et_times, kernels): """Tests create_rotation_matrix function.""" - kernels = [str(file) for file in kernel_path.iterdir()] - with spice.KernelPool(kernels): - rotation_matrix, z_avg = create_rotation_matrix(et_times) + rotation_matrix = create_rotation_matrix(et_times) + q_avg = average_quaternions(et_times) + z_avg = spice.q2m(list(q_avg))[:, 2] rotation_matrix_expected = np.array( [[0.0000, 0.0000, 1.0000], [0.9104, -0.4136, 0.0000], [0.4136, 0.9104, 0.0000]] @@ -113,10 +114,9 @@ def test_create_rotation_matrix(et_times, kernel_path): # @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") -def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): +def test_create_pointing_frame(monkeypatch, kernel_path, ck_kernel): """Tests create_pointing_frame function.""" monkeypatch.setenv("EFS_MOUNT_PATH", str(kernel_path)) - _, ck_kernel = create_kernel_list create_pointing_frame() # After imap_dps.bc has been created. @@ -141,15 +141,22 @@ def test_create_pointing_frame(monkeypatch, kernel_path, create_kernel_list): assert (kernel_path / "imap_dps.bc").exists() -# @pytest.mark.skip(reason="Plotting only") -def test_declination_plot(create_kernel_list, et_times): +def test_declination_plot(kernels, et_times): """Tests Inertial z axis and provides visualization.""" - kernels, ck_kernel = create_kernel_list + + z_eclip_time = [] with spice.KernelPool(kernels): # Converts rectangular coordinates to spherical coordinates. - q_avg, z_eclip_time = average_quaternions(et_times) - _, z_avg = create_rotation_matrix(et_times) + + for tdb in et_times: + # Rotation matrix from IMAP spacecraft frame to ECLIPJ2000. + body_rots = spice.pxform("IMAP_SPACECRAFT", "ECLIPJ2000", tdb) + # z-axis of the ECLIPJ2000 frame. + z_eclip_time.append(body_rots[:, 2]) + + q_avg = average_quaternions(et_times) + z_avg = spice.q2m(list(q_avg))[:, 2] # Create visualization declination_list = [] diff --git a/poetry.lock b/poetry.lock index d7d07d3f5..38e475799 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.0 and should not be changed by hand. [[package]] name = "accessible-pygments" @@ -2225,10 +2225,11 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [extras] dev = ["mypy", "pre-commit", "ruff"] doc = ["numpydoc", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-openapi"] -test = ["matplotlib", "openpyxl", "pytest", "pytest-cov"] +plotting = ["matplotlib"] +test = ["openpyxl", "pytest", "pytest-cov"] tools = ["openpyxl", "pandas"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<4" -content-hash = "59a44fb08c81d71d3ab8e0ae21d87cc1a6db18386e16eae69146f821bcc43607" +content-hash = "f56e3289477dc3ecc3c98e94297e8a88fcf973d2c0aacbe7890238fed878500c" diff --git a/pyproject.toml b/pyproject.toml index b7a21cde7..c9d6528e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,8 +57,9 @@ matplotlib = {version="^3.7.1", optional=true} [tool.poetry.extras] dev = ["pre-commit", "ruff", "mypy"] doc = ["numpydoc", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-openapi"] -test = ["openpyxl", "pytest", "pytest-cov", "matplotlib"] +test = ["openpyxl", "pytest", "pytest-cov"] tools= ["openpyxl", "pandas"] +plotting = ["matplotlib"] [project.urls] homepage = "https://github.com/IMAP-Science-Operations-Center" From 295e4e8fa524dc68fb0be3ef192d8234a47d8cea Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Wed, 21 Aug 2024 10:28:11 -0600 Subject: [PATCH 13/32] pr response --- imap_processing/spice/pointing_frame_handler.py | 4 ++-- imap_processing/tests/spice/test_pointing_frame_handler.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imap_processing/spice/pointing_frame_handler.py b/imap_processing/spice/pointing_frame_handler.py index 90a01666b..0f3f86776 100644 --- a/imap_processing/spice/pointing_frame_handler.py +++ b/imap_processing/spice/pointing_frame_handler.py @@ -8,8 +8,7 @@ 2. imap_sclk_0000.tsc - spacecraft clock kernel 3. imap_wkcp.tf - spacecraft frame kernel 4. naif0012.tls - standard NAIF leapsecond kernel -5. imap_spin.bc - test attitude kernel available at: - https://lasp.colorado.edu/galaxy/display/IMAP/Data +5. imap_spin.bc - test attitude kernel generated by simulate_imap_attitude.m. These need to be placed in tests/pointing_frame/test_data. References @@ -168,6 +167,7 @@ def create_pointing_frame() -> Path: path_to_pointing_frame : Path Path to dps frame. """ + # TODO: this part will change with ensure_spice decorator. # Mount path to EFS. mount_path = Path(os.getenv("EFS_MOUNT_PATH", "")) diff --git a/imap_processing/tests/spice/test_pointing_frame_handler.py b/imap_processing/tests/spice/test_pointing_frame_handler.py index 949a2c140..3777b8f94 100644 --- a/imap_processing/tests/spice/test_pointing_frame_handler.py +++ b/imap_processing/tests/spice/test_pointing_frame_handler.py @@ -79,7 +79,7 @@ def test_get_et_times(kernels, ck_kernel): et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) assert et_start == 802008069.184905 - assert et_end == 802094467.184905 + assert et_end == 802015267.184906 assert len(et_times) == 57600 From 373be7ee70daaea29f1048713adddd125dfc4b86 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Wed, 21 Aug 2024 10:28:34 -0600 Subject: [PATCH 14/32] pr response --- .../tests/spice/test_data/imap_spin.bc | Bin 0 -> 293888 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 imap_processing/tests/spice/test_data/imap_spin.bc diff --git a/imap_processing/tests/spice/test_data/imap_spin.bc b/imap_processing/tests/spice/test_data/imap_spin.bc new file mode 100644 index 0000000000000000000000000000000000000000..97459719a9d9679a2437df098464c88b3e702baa GIT binary patch literal 293888 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%0A9;NJHh{k08_W4F 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ðZLH&2n{@&;h z7aFm-EhCr=#LwYYJQfAdV1BGaSAZedZ(5h{NmM_(AZ|2P7f0}efT%)FWL6`V^ZaSn zQb83Si6ux;v?#b?`ee#7==WDbBKHf!{s~|@cmwf6^oP4&{45E6XsvPhcC4Wiqizu< z%|rb+|G3f_anKVyinT1%gnZJ#oq8p-e~SikR1p8y#1CKC+)dcuZG8dGAjmh*>Syr3 zhW@LS<2@(7JHVW&6YNpSkk7he+5OiP&X2*IehqYf$i?y33mXyq&^10YZZbQDg-W>c zWLyOu$<|bbI?YOq>S5V_#ZlmeKlSHX;QXT49y{|I?C)%*ltBG4f*(q^SPh0j{4BTf zJLzvH%&(K!uF>?f5#Pao?Bl@YYK-TcS1AYBAANPP{{%e0+H>gU({h3znosL1%0m9i z=c{}<`N=3Y+g!>};NWgYLm+t^w~m;PC>T-ybiyaB;sY&~~3;Zv;wASl7Wirm**x!ZtL5A_C0jfXPf0X>3|CR8+|2PLIgGnUJ z#m}M5?RN@hG!?s;4*6&GOi7h|=)W>Gv|DNi|Fvqx{RHvD*KgOmzX}uluw*p4Lq01F z>uA4r`R}C;oOgV!`3ls3eZO5k$PPND{1irhhbrDhNX0Z9~3>Nw|4_C zCrH|8&_KV|wrnj<>HQs8sd?NdY9`PxJSac=1mcI-Z*^o-u)i&*oTGQl5&rMDTE^cE z;NL|1b(RyLA0!`q6m&;29X~Cy4sw^>vypFbr0uUdGp z4Ji%k{~_KCBcR`RRo$dJR6@d=#@ECX&!yl3^cAn2A%2?DwyQw#(__tiKd?_f z{8lG3fho{hZR?kZInGARf|U?ISM}oy9+yct9S47pBG{ixYpFPj-y++YFCX9{`j;;J z`#5tpmyE@T#EkgQ!8zNkuIoja#7kNu+q3VF;^_ywB8(t@6q8Iix*OiV$DFgYCy3yO zC_DD1pia;Yhq=;H%U9z|d~((gVE(gAN2U=?%Ou`d^KP#@#IHP4Z$wc18nWqmpYk7m z=+RAMxffZ9IoykEd8s_d!n(ebSxomNo_JsD8g=5#r~mOJ#05;rmzZeB`~# zLfGHJ-}N6P$Tyc9G!4{({%1{k&U3=ipi^wt$O(abmX7(AYkjc(TUa98Q2eg2ckW=- zIf5S~x~(jkAbviW`-(jh>Ofw%`MF~@DlxltA50JC=Ty6eki5YDYH>*t>R-AMG`4Hc zx2ON>U&?m>uFM7bt6qcWij$;CY)y@+ydCuW{@dBN@64~l)O0K&>ShUWESV453fa#<2dAQB1XnAD({n z-Y@x#s6WVV>DwN)Ed%S*k?>`A>A>p~Qx}z?|4MF;XGtyeQ3n>QQ>%de;rqPQ(~yRE9^L;i ztTZ)o?>=EaZry9`^}xUMhwql4`+o!0n3FnH(s32rh!7opm?Qnm>voAwo- zUcLt(?rP;fBKSd6ahaMK`kymBgKzJbX~Y`$OjJ5T--XXkNq4!3QC#q!n z@nOjR3%_>xx79e;O$n{{yTqR4y>7po7!K{?;reQu(2@&^U|A>=J$gA zv3O_QDS+n-k5-P5<_Ug?KVfsFNE7Z^lONL3fj$h&?!g;hVSY~5=R<;liq)8P#a{XA z;Qu*aaTOr{pU1YM;%!9mL)vHj;Vj(0FfwRW4LS{KlwC&J=+DNs&w4^xQ5`KT3(cGY|LwiZOZruF)jprSBZc zA`t(uXl^K>_@{JZoyJU`;D?`0hm zK4OR;L@wrq;;??-D;*u@Z3uo~>&L9gV&Jy$(Lt4R2#kIFsoXj1V0 z&0zWhus^D^$~1@{Sda1Bo$(_0!MA9?nZ{{|pB+oEpGst`fQnl(7V1Y8tWvedE|Kum z+p9nG;CXKRR6KgVFSb&?&zsI= z{?89#`2EKdvTmaKLy)GW)Py6!4=ysC)n0Xt*x4kpxL-Wg_|;OlBtV@2p^d{-1#Ph*_~DtkF89@-UJUQIpP~l+@7ASlmqwtUV^YAOHU#)L z@Agf#5wIWUxXrVOKgT*naSk_v9}M>8PHX^gi=Fw>B?a~7uwudUFV-tDdWmneN6UIK z8S8-k$bNaFA}%BTwGBT`!x&ERLt5Uu?~lQ6w|TYe=X6YBoE5hnkHY-AfC%=c!MZ9; zqp0t$80;SpwlXfXe-8cID(|ID@B?1Gd1&RwB&M^^L2(%BM^pX=pK621_+~_)OT>vr zd_zO>|Mb)9Zxm(G{%vCyA#dM7@B{lo&xAMV7e){4{4lOV!ahAQXr>54-N&DNA;FZ4 z^KJx97{mGTT*2_>Jy^ewY0*CA|KSH)rdLwt%_MBcaKgQpzmu_&*PY#2Q55{rRBPy4 z(Em!Ez953mFA=j9DZ~$qQxOtkOU(bvAA2aA3L60b>-2uXzZvxVVwwlE&V&BwvyEq# z1@uwlpZabd1pE6jb=?>7gIXG=ko#+bA1c+O4M~66F-MvPDRke-a$Gt8gOOqE!|y9v zJdjuVe@vZsJeU9X|B)FH8kD^fEqj!%j50E^$*9ciB#C4sL^c^IdlW*EWONxBC9=wT zA$ul7DV5)Oer~_-`|8jBxO%<3uJe4Jb3f-i&WUMMaU6mBo2f&B8S%q8)4#eX(jTd+OpD|0O zmqh*Hc*_Mo`eT#W?#a_?zV;-nh_uR73H=+>-6bJmpkJU8{n|(c{##@v;8!7he&!)} zzVCSiKe)@bWJjcuFwMGoa_hq_7-uDwR3*$^|6L#7uLJtQ?o+JA!4N;R>E6ym@x#>X zpfaV;g#TNpcRwxkwgp=W{K~OD4f_40?E@{KAAC`IB)%2=uh*unCelBobI@v{_@(k! z9sSTv!v9uz{!+9Htj4a=lX<1S1%1d_ufPgm<-9Ma zqx!>!-)LK0AW?t#%w^a%3;My!Vlp>wL;nVIs2fLfAqoFU9+0I;5BmL%!LNuP?mT9R zLh-ZqH90eKTEhPJxQs{d0R7-`7?oN8{gWZICw!x2VQzCu--~0$z|pINT7B^T=iC*4 z+<@ODZQ1f|14i&ea=5+yW@;~{|6+P@OC<{n3rc(a>ESef`qYCVTA07FcCx!U0PHXN zW^g6qhefr=GkT?Q|MA0YTzJ1oUN&Z=pv2j(-ib$ke-;=4`ri(Bcis}vG0B#dZhnN% z56*U=YC%JkReue1&vQnKjIZq96~M_^SHls~nuxjV!|y`X^^D_hlKw z`}cK;@J9Sdb}3Sk>MFqx9YR9>5};eUAl^Qc5A)m4PIU|gH}>MV@^hzz=?vI^uAzhY z_4&5_Qiva@pM2?hH%{=wfcEK`J(8f`*XO>KqD8_MM1%g{g1xASbbN2JaV_Bb|-fA^x(A5n2=>?rWNASN+in3WkkbfR5*-AtA zPuR${!UA~zZqhe~Hwp=UxNB7>>jU{_+JPf4Yse=sU%}E3vcSJhGM_bAVIHN!iUsWh zu)jr)LLGGfJ=xFuVz`Rnhpy@`1M|S!SYT^9HNllreihO2=-MO z>EE)#J{&;&&}+yf@wlF_KZ~W@6=~29J~qOxP=bCxHaqpYaV*5oY(KuWakSu~!wED4 z;D2slUtb`8h&Z>VLCH_tpD8uPmz%-=%GMlu(g^wmkDIBYbw{E8yGnh2(vXA;PB}EN zf&XK)_&tvJ;g##awTe7~ALMT^g>3`<{_p#{Vn#wh)56Vty zkVE>*M;sr!Q2z4txZ$0sO~U^4Rf_AUdq**?*Lm|IkbmAgE%fp3{!UCejD@8h@?j~W z{&6V&89n?c0>wWRH;yZos1y8<(r?FieAg5<=orRm208@aZH>d-ZP_@3%$;|PXFFjZ zrbDg;#9x2oCyt`{%b>vau2?$34=2x@i@cQ#`(tgbUHD;t%5F#IU8~SPIViO0p|6pJ zC$!pW&w~989gC$~f#qXjekW83NneUFtssy|DC ze_smYSJ3{4fm_ClX#YdS=5~%DW+HwwlaI*{7-+$4IfmwI>1uJ_xtBA6;D2*3KY1<> z`u*zfd65So{=OC(?uGavn_*P=zAM2GP1-vfHEpV~_(uC@axnj@yzIT7eNs#`|AWh+=#QXa)!@y(V1mIpI4Z4=p6b!A<~-a==%t~VRsXN@6Rvx zIld0Q|0wNot2!rw9|ZJQzQf;(%}1ux!{3YD6&!pCzXxu3;>^#NbhX%|g`pPu{mN$V z8X3dy_dEFB_hxp2Us?Ja)&0T$HqWp&!tafxg};)4_kni?F+a(K^Q&8Ex%>^@U#W7? z8^jM$?DCJBtt9dP+n;82Dpn#D{O_N@-S@GZz1WADYrm`|C-K6*tG-|lxPRn}9aCUG z6&lN?t6)Edr!Eidj3W4flN+o0mez{}yxDxIs*#1IN10WFJ>sim=KXwvlQ_lC5Kn8c zUxvO6f5g9WooV}xA_#skrhXwg+Lnze^t3Cm0{`-yDzA{=HHFvFtvxsoIwlFm;A{yv zKgAVFWX16P71(n^`g90>=zUq57z*c2PUhesI&Y#~R&UUGOspJLcQ|EFHVtrT|X6LIKLG>VRTk*~8vHS%EXxS0 zKj`Exd_er5CD`t^JDcDKg;zTSE`z_X%evhu4F3Lyvi!RkhzGo1Q~u~~hJAUwAA9aW z{NTz;^Blzwhi<#dj*{f_(nL?IV??61P+t&VzAL80w z6KkGGKTLJ=B|X}Ia9TpzftP}?KW`)Eb_R&I<4mr#?1gxH$e5H~3-S1BV}6Ph#N%w; z_mWZm-;axT#T(wg!`|04%O?naAh#}|fp{NF)+!x)3OfAi%&(1(dD*yo&!KZ4LBBt9 zpNj?Q_jg&W-=+im+xD02=RNY<|Mf3*>+#NggudxRA3lAff&HOB>Kz=nfqtKx_A+&o zN)|pd8TeojK7URlQw4oKlgrly^J4@*klAy%M?(IJ&(?M?@D3KWxs#Ix{4f3Up~37M zy|^^xL6r^k_rLsJh5mjI1K!d4O(Oo!8aw>Fu8@Qstr&LEhWMFjREGNt_+OcZ??V1D zWB8Am)*AHtYrkb}L-hv(+GLX|U*h>fy@hN|*uUUS(wu!KQj6PaRDPQP{r--=X&EKb z6i)q8>bX9=|D&4=QA}WeiV7!bllbBc1dNy{%6iIL&#q}pV)ok67*rF z-;NjQhx^x6W4H7P_D}kaepn9(fNBozNz3d|56p?o4!Q6+I0`|QBYQM{RH`_ z@tu#7Q2k+5ooyBQ9}j2W{C$GN{pm0hm4NbHGa)Awg(2THHnudj2>CF9=(B8n;D6&; zv*dPz|6}XjIgavY-I=f7etAUj!wkKH_^I76r#Aa%vd#TzjQhY;n#Z7W2(H5I=C{={>u&M%W*xige$5*uTJrDa3|A{_0^JE5)~YnE$DA-+m%s z3|IY4Mkx*PkL`fT38epw)gd+8sS^AU<9hy^0_;D!s&Mr-MPm)b&--(4TTbI0536O7ItzEpN8xC_`_e>t3 zhJ17io%i>j5Px0wCXg)Knzj5c1(HV}@H{ zkPjC~C@@0%laEWEltKMV!cx>x760^)T>d-6vG?LM_WSXlAENCa$2ZSSVSDDEqz)ke8KQBy~Kp9h-N4Dt3&=OU>}Fv z<{1*sxzmvKF+9I)?pK5A4{EbQU4NST!>@?eE*$lf_AMJ34S<_vr;ho@IE$iAy!%hKXe~pDt!w32iwCcznnW=i|;uQC|;>Ojc-(w zsLu6I;m?huTWR6`TF>AsC#U#)T<({-LBYi^xCx5G`$CQ3}6nidBFI3)Fkt?p5-4LOs}J zY|^v_>cN9vl8?IK{-)R5!Lc3g@4sDQ{+IU={?DYYqqZ9OcPn+8mih8D=6KUrwgl?Y zkGcxZ@j*RWMC*AO;)fS&d$&;kYi+lO_s<&Q{#)`5BP-K{dnP3Q*kka&jykdNr7t1x zr0TR#+ERl_OX=qhf&WsxtX7Zwmt8GSodh4j4`Y{x^*y2Qa_2DzS6SfS<-u03{qZE+ z^ZX|HhI|ViWu7aa1NJ9-YRZoc{3lPA`Wx9t1V8K+ASLppjbVv3Ei_@*p?>tep;hG2 zB(AK$Xgmk~lNZYKtagC^)_9$7jrs>xbJ}d}k_mpudv{;tVNox(O4gDZN}Gk9fc5OZ zVE@7i(@YI@&=2aV@baPf;Y*9bUKBs{C&w|>_7naunf_LDpIQ#)W+EPIW(56LM;2v1 z>;P_}Xg)U#`a#`t+iPnOzhnz;-9hn-7~Sw5FK5F3Hh8{N)Ih(5xPOOa5%gO)*qG{0 zK|cmryuQ&W_}`=>VI_7DKb@_XJ*^D(*Xht(oJJz}!AYs?5PAP7R_FH30QGxN*3j9U zgnkgRhuq3;P&(OJ8kAEtSzup4NrkN3`%w@ zgA}>=$-3>qbRM19`1^!eU5Fpux*2#-{J14b88GHT@I%08$P+o>=G8p=&=vkkY?sC! zcY~H*d^v=3Z=+b?}51XM2B0N_JepsPP`z8ealW|?Y6W#1cSm?uQ z;d@16_#?hU8=0n{L;Mk0_zU9ar5obxD1HY0oN&N*;`!#2Ro3GnBy3uj=Os7vZ#>46 z24!G=`$(U?S@WGS{LOmwk@DIDf@1Jpxr4sQ2EnAKP<5l8$^Z1!zZ))X@fqV z0J@#tJuSG~hMiN5VlB4pJ#iSl|AIKbO!WR)voizg|EWLR@<|Z)oSwqo(vg_UApd+a zhwI1T0*HGH%b81-n{kg@5p2l*R(^dPLH6h6Fw~LlOYlR&T|MuYd1F|AVrF8PVK0_- zuJCgu^ly}?UH$V7_7BQ29ejf9f9}jva>UQu%+sR{#t44kHB`^wDDTC_tA0*wC}d*W z%?}N=W>4dMtU~->VE?b;f&7jiaQ<4ecv?{Z;9^#H80$si{&LpIPKc7s!7BH>-)yjh z{lDj$y;ecL;QVBnQ6Bv7+#Z(rNI3tb8*BpR@cX-JC?3DpN8F#GY7fVbLce3gvFR6- z(C;X0dv>`R`XQT1+AFNUzs(OP%b4K(FFxduNB57ofy&^KV1geO8-w09LBC}IdyroZ z^jiw)%WUd{{~cWHOs0bQv2%xIA7p_2iDi+UL-!wl%an7$-J z@zdDa7hRt1kF)W=RA-myV19f4vKhw++`lvXg5RS0uhtCp>3$A^ALMX9m6UAQo3(!T zcR3r(Z(lz3VlBNFboQhGe!)HT zDrdhc3Fg=1-#SyraI<40vMx^0M}1=9Y!~>SmcUzPsQ&PppFeaP6LEj$88(UdfPPSx z!$0u(GVE#FU7e>2x}nLl$6E*Qj^QKQhinl)BoA?=&4B$R9(LGc{*d4YV{-o8u}dv5 zr^MmT6~kIQ$fGkNL2nw@WLKU10rNLZUuR2@gZ({O*AGYhVE95V`tm>Z2QQ{qR-!u9 z7*3hmDL4jkZ&6Y41?Wds&~DK$Fqy{KuN`yT#1ylHkA0n1lW5`^g zF7xt_wH)~07*orf;5*_hypxTj&UaE7oyeL+eJ1?ac7 zDBXAU6!0&tzaZVurfN(*IVz5}svmn4=SC$7@z0x|-R}@TC=Y!zf2K_E1C=a4(~=I{ z+XJdbiz8Fm*NH~c7x^vtevgex)6yDD^2oD4mm&TNl{%)_1MmNMy^GM>7=j=2+uIkh zVVHBg{X}05%x@nabPi^VAmO=jPKn{5Uy!6yytM@Ox0z{r4aI-+=e&)sTp{=&vui6% zGYkB7BZtGfTQ6oQLHSz;`X}3(sO~y~evnU4F9`92gGB525BUB?dn@9?O$dIt5x1nQ z{Q{ory4j)LmWg@$CB)7_-iab%A|L_$FKg4R5{iF~bsJ8g{{5~=%<%>dk^e1Sipu;D znS)jPeR8a}g!z;Ccc0{dey}~4JX{R?Z|t>Edmf0tqxsejBYucz{o3AYK=6ZqkkREV z&>K|U9=<^hdIJ~ISt?KPzpc#$7N;TqtZBjJlneG(o%z`o@k8=3(|cx5f*+i&7q|3) z-r?M}$&qrj)E+dgQ*{**1L5$A>}UsUbw$mzBvn^{7;Nrf}I`% z;r|kYxpaIBd$9<+q0Xd$OziS{Fz+tV55DtEs=U4n{-0e6UY_7TDs-I=Apen2cz=HA zpZ!asV|m*ZzCr(F{!=ejIKTJB9lJC@zkk@{xY~=zY25x-rsyE}FJs33XNVt+IPCMB z_7MD#_Lg~DC|4);s+WoWCFuR)7L;%LfgW%rTSeOm>Omxv9eeV@{{GafEFu5d!+Bu% z;yr>N%*h^%On)22Jh>DLi=YpZba5_83iOC1ss&jN&?8o9+%rM>zy5_Yu}|RhkEV#9 z>$*em!%NvJl~m9#i2GE&41jaE+~bs$*^!OcN>4aBnsj1k7)G@bKis5!{SE0K{P!L( z*JvjE-3(%)FLHW=D>b9DD-&_uZ_?dkC>98c&pUwd#=X|gq z1=sM{G;4w%gxV7wMrT_v*1;Nscd-BWE;+5<9GqXvkD}y5Fn>};r1z*M#E&}|`ZG}c z7`i!5<9~tRhdfRNVSmuuUV3+ajUM#2Iw#E=OCWys!On^OFqp<_$r#*F|Ggnoeuydj z{awcUzE`^v@qffILC!s(_w6{NU0wzGXD;qFw(uC&%PQv?Foqsgq z1@C`Fw=2YC2f+{PX*EHV@I80iE{Al1j_8ZtuzE;p3*PqVps7_(4HjSBbPvtXj2Kxc zLHzJFGQv8GMejd;cz^T}eazStwtLOt+{(Q%?B$I+AA>_lIIR$Cdn@e!^>RC8g!q9z z!tNTsb@b`JBv2EbqW!BYVgJ#jGqb-P=>2CpDJd_)JOJ&8_4po`2Ouk0#ew)C zl!n~_+5e}iz4ZGA34Wk{mba}9^n?7R?=*%orZJ7K(R0c#b8sG!mS=ZuV6UmezJ_&F ze>lGCiO%1_-T9U0jEMMcK8pUjV-)Q9c_Ja(4;;&FGcU7J)r)^+NVy#RC=>s@?G+XU z=bv2RPM`(+{<7L*Qbmo#{aF_NLQfp}E^}98+~h$&xGMMAT{3qJPo<=CO?2$VMZN3s zo$&tMALfOl`ok%zudlnp34SnE(uF{(o$Uq`+sF!POR^PzQ_8pQ!Xlyzj8VD zcQg;|&%VXyH#yiJOC^bnIf>whD;8%?Go`m+SCo|+Y4U4ur`cx86o{X>zH_(yg!)nQ zy)$+sxPL7!RB|JJm}hNfW7$pcLz~w~iyq9oc-E%Wlw1M&(r~7rgxPUSTeRs=ukAEe zKy_#y)gPz}N( z2(bQh4b{KJyEM#@|0%lp+GXV*eh9E>2tEVzK3?t#UuQRhb9m|`v~E{pS^LCJzJdEh zE7PEr7X07Wm(`b$|1*i(ow)Np!4IDXk3G3&IE^v1d=eAsn!;*LzJ$3fwBTyyyBK$a zejlcSS5SccbtlM$mBI5fcZ*VuMp*Ixn?J#6Jl(qq@w1oW&dP7WV;GO^8-rtIaDMY? z#%vdxab|Dpuyf%5y(|87qWs~9YNY^OC5iu@e{VT5FAe!C&!^kJ6x;S<8B1BwfuJ9B zFkWzrQ6b?6mDSDB{#qvf^52LbvbFQy_WU!y@GGoNo6QFO@6L)V6wR4f($vF&moPu) zLCv<*gguk^;_Yn-D1T}uVt5SoUx-K)ERV?%{2+wCtMtLMG2_Dpg-wQ?xbt@XSATe? z@atBdY!4w1HbKKW>k9Fg*OqNfC%peV0#+&m2?RgvYtC_xg?Tq0Z=VqS4)bobZyxU4 z2lH_LUb=qr2l&PIf;_iXu)n-FKMx}P!~W}E4Ymam{9tr-AA=(B@?)vK6hE#hOuCw@ z{4~ttnfS_-$_4Xy&c?P>p!~I{gmgOMhxq|17Fk__AMVZ<*O)@x>Ge-xpB<4V>gXQJ- z>0urc{z&i4S?lxAKly59Dh=#!fVcTl3)qi%_;iq-1;GzzwI4jTDkfn&PZjvtFT&^K zTL+D3p%#cAb~Y-XrZgb-VkluXZyAF4 zL`{Xo8|G2P3N@|Tfv#5Q9X%W32RmEIGwAobHNQ1G@P)Yl3LX`x?|^w%Em{4CK0yB! zrMpPDXguthefs*%IOMY=4$mL@4ew7xXn7L7KUwy()ty=dKREPV;S^aK#}Zy!*c(H= zx%SFxr54QNa*yO^uYh=d@LJ*pRDVb!E6hXuIi>PE^0Xeo4>En>H_c6^G5buat@ofK z`pTc%H=odg)A`!H4au#+HcHLHoWOpy?)q#)^#|W=9~O$P5&S@|+wrJz3i>X$F7@TZ z{_a7pAzkJW5-uA-9(W1n*V*p1-YyU4=hz7wj;HYb^&Kyr43#1HK{(m;$1SKI(ROXe zcV6hl=+Cf?azWiz|5fmgct;ZMX171h6V5O1SkNUjf9b;AZJoQv3HysLS`I()rWYHE z<`nT&&cqUbY+Oi#xf#?;{jv^1lX!IRdp5)mJsNwgQ2)~416N}^S%M!T9G16&zvW=m z=1=Cx-8ykkw_dsTbyL?^)yf2tQ1Vqo5! zE7z=)0~_p5VZRqh-7|_!d(*0ELp>;*%TN#T1GBb57^**PJevIOdY9k_n`3UZr-7Gk zF2<;>120c2n^s6sbz;uL4sK{3o_QHL58{WDSr_8a{T*>IJZX}e@PBUo`*=Qs|IOof z%8t*P#>k>o;!bKEv2>NRC&+&&GgJj5|3P!1_5RU3!u|}~qxX73-0gZk zRxlUzgBBIkT~^O~ai&axOOu~7abugC3!jnylJ?_8{!7Yp)JkhN!4EyLo*($(xmz;I zM<-!^j=~9sJtG-o_%}`KcJr&fc;o1;kV3FOqx9p2f8qI$PVWlYf(d>Yc=sdrL=*}0 zUc^OD!Th?kO-z3l@>g@&2F6*?ztQ(cr5o{s8BD z)|d&utijJbfTWo=%zsYqxs?lXxaITF9uz;A8UI~I{Gj@X%ghre_@QlSgSxw_8f)@; zJ}CwB9+Ms(5k3R`8(CfroW+n&D)Y1DMEy(3*KMAn_+|5pMOnEfVSnE!`a&N-;}3Z_+*JyzT>MIH$9owuX?;dVYtM{u0Db)*Br(sQ%C`Q2TzzKlKMb?VbKhFz?bM zTSOEVXJMQSk5t!S9;QNY`oT)@zagqidSYOIqq`i_^1yyVdF`Hj@g(>mcZ%ky9OSK? znfAYdd7D_l*YcoQ(C?>+jmb;v)?&wCGny8}k0NOcRLt=CHd&?t6xswo&_z}TvJArh z4hhLEjqow-%!M~0e_(#j*p(+Lt1v${y?bWE3F22rE6Yt3zglUWe5YvIHFX#uQ{`_L^KAVHruzg&(<3VdEYBUc6E*Nl_f^FG|j@^D)?;Yxf@(jvE9& zY<&&;Se#G7s)sltH@-DvrtcolKc1PwT?*q8R&R~rh1sFdvm{To6LAMStjZVKAy}*{=HTf%l)}o{)v^pW3?t zlUW`FKNK{%7CEniet~B&kQ3E`obvOyx2myasp=EQV@P(4HrcHh?;{^_nx)HJHDlTNSha6Zqfxj;CR{Wi^r56UcjgZ5_CkM#4X7&6zsfMRW5etKxljz^iRfrHROzDnZmOrtIlgeAN5<_#SJpBzlkoJc;tU) zcw*i?n;`f>`2K|Q4Ag6zZYSKefPN{3@wf3!FppitBf{Ya)Ps(XtEcIL|L5-0FhKke zm`M|)eS+YJBKF%i`e5GOI4{dXa)~MI(q*HiESLv>{-BAI7UaXeuh@L`g80LCpHn8{ z2m62qvzwiS{XI5(VVeN?=j4l&QAKbL9q(^hmWt)zm8wgm34NHK)4VGc^)Kayb4ww9 zIDGk*R-z=q4-Q^x$z*ZU81o&zs#f6NmvuB}MxXTJ0`g;WeC%0xP=d7ERfxZWsq>l< zKXAK}pH2@U_`x8UIo=lbr@R^5dsxp2{HPozGWT!{4?LNy$#J6>SEFhbTnGE(3A=%z z{P7j(d6&401V8v(z45I7J_&P5dbYn!x&CZ_5A?qpPy5!kV9LfZ$FsU>@Q`FGvt{U?+;6L$`w=*ra`;p^ihmXK zvLsOaJNB9HE&UI|e=6P8IL@40jr~2!GCJ7^^L6Wj9;iS+#h<3(hz0P!3f+YU91wqV zslBP@e_Z_n_*owq_6Y<{~F0wsehZOsnP|g9GHBokB`=Qs8+i z{c9f)e~gH!KJv37_@S0AI;T);8arJvQBwka7=_RLq^f{_4~mGh$tl!g#TV|(al`kQ zp_x&thwtx`!l!;&o!|$CpAFlEA?`Lcm6BD98pG-v13reAknq@EvZWT-pE8>H=r`i8 z=;M2iApP|8LKye{6~g{TjK}j!LBH^NZZYOPge;Mp8PEA-Q_@U`k-Ni-eN$k!|g(*sy-|nF4(vwy=hKv44yLmvT7ysos z&q)o>pC7VipM~e0t3?W>!wG(HF8bYLpH9MzXz9)m!2T4nXj9hM`6>M7PCCYHUzmSo z)IHJx_jlAL$1QrezYW7UA6JnR{%`EP!k(g<7HmsPox6WuEnf6ZswxTe3&JEL>674p zcL6$hnfGgzqP|Ayw$tD8jCvgWGd%9?AO*^@N|WKMw{TO;U)0D zZW$u9D7!zZCk*;2x7#;;(}Mi7 zlTbr)DcGOzK#TyYKXkg)J#!Bv_<>vpFWUk8mhR>!P=7Rm`LWei!^JiHsHpeJe+=8z?51E z;cFR#dXRD-jWf!B57T;FIuC#UScA+V2_qu@FR~ZQ^n?2En=5wcxj*D?_MGX5pU&);m(b{^Ezi-y!`f4^y8JPsigbaLPe`vx$m&kTo*#GM% z$GiajlNU-;vj2j9-~QdO;XHhPvUFv{HTZnT!l6->a=dUR(9B9F8 z!uN+tf_^{5Q9oW9^!sEpW2NZtZ}M|%Mg2=L+4|BPqq5ll?N7V*Wd3|(M+=s>U(WpY zY7Oqv+8C4o`oV-9LVGR2|IWWVsp1H~zocya9O@st%wIibWJvIX<>-i?s29witms|2 z1Lrq|@wCJs=m}c+MfL93O=D*c88&Oc`%juY9l-+cUnAzAmA5Xz4>afR+7>~+ndydQ z<1N@XXcAP|dJTT3Cs*TZ4PhVQdVRy2LtuY%fg{bx{;u*et{*>6@I$rMMrJqcJ6yf; zXYHodG**{S6O(vi3Qj{W3t(6WdGJ>XQQn<34XYLM)$)x(C_z? z=kggr9=VpH$l7AO1+T}FJ@)d{Vh>)?pZE^vucZCw4#W>rXRn4lS0(&siOsOv6X52I z*(e>u*fH!u%pNwgCnTKSi?oN1xdnHZ=GsFRnoR?BC>6`V8!kt#X|j-G5$2>}L)>B>3UVQHR{q z&$6-iNe!|T;D0-Bq^j-RJB5?WEU<1s{z~spiRBpFzpp(P_R7QO3tX4=r=}Vc&L21`3H6}pmht*)aQ|CBGM7jBqbtpCPtX6e|FY?b zE7@V#H)=bsL)FhYg-Lq@*=)3Gog-mGSI;zWJca(N;r5@ipx?*uc3UI=uPr*WjQC;w-PdwPX@Vbk zlg{zINre5Ow~iYNGq+%8-DK`FfPRqkiY)gA_}^3~wi?vGWH(=CiQ%+M(Y}DY7q{yQALBIctp-3nM=GR5PEi;gX_=h1uy|@VM?-)aeWt}L& z5AD10=eI|zF|)DOWQsR1-{9f(4NCC8ifw61YzCm`vSy9&fcPs#%wPraLw6G8DFqLL zABG1gnNC8!Igq(p)f4hp7yrgz=}v(Ehws#@6VQM4?e4(lCfFZqx)}8$Ja3??D7z*` z@B_Cr_s2WH+s59)Z5)Qv*h*Z_jm{a+L&dFhsMkZk`PY(C3L)qp6c;M}iS93^Hpy2S z1V39`cw6D?6p3|H}0F3}44$4JIqrtAyq+ar;CIqW=B&s%P$_bP@8;hr{OFVgJ$Rf>|!A1QPD`J;Qf(PYX`DFFKVI;_qkoigi%@J@wOJ_ox`uZ3V}^GwG9XJ+e1kiC{nb%4jIxf&E0# zIvRKV!w>ho5`I5x?!}y>8EsldGqAT31=V^Frty*q-88m+5I=`Xd`N=lzxBS(cni;S zoxOUx^&G(uO81`I(GBHb>ZZw$Jz;*%^Q+>*+aP{+6%DPDg!++HY5HS!`2NSQ4bUL{ zLzd3s)n4 zs0$V}(wryk?{lBjsc@KgcYd+`f$TA;*Nh?bygZFngXnjB8 zzhFmMoaY~Yz~8?T%Lo0DbAC(av9xJyW?+ZhOl>y4dSuqbO`{WItvujP2KIOIL{!H- z*w3xjB56()f*(%aTYC5{Wg45X4~lPx{%3#czg7*8dU16G_Am3~non zi2twHEVfNF*WyQRtp6AW|C^O@W1sHG6poj#Kh}i%V^iSh z0^)~~ZSzNh4iNmnqH@#mk9jpV8lQ0Z6XdV1QMh*O0)NQhz-#c-dKycyRd4+X_A|SW zW(e^^1f3|2%rLR$Wb?@R{Rp_^>U_Mh*%5Q+yln7CNH-P<&-?o-E9-Gi#$^l?DAiE5paNCD`9x#w;7+YemAX6I1ic;r>z) zNfg+E=f9fV+-duk;D@BrYMGjhUhH8>L;NS0pR*?Zj*lg28aGPUEY*Pe(Z`#k!`$G% z{dDeSBLA)RJU;n{55W(XJtNgnnh_MS*k{D2r@-3-^&p44=Q~jU z#2$55cEk_tRrQ)e%7pzX`6ecunI6T=x!v=gK_7F1spO;Gzdm4g2U`uUK|Fpr^u-;- z4Su^DPGtD*lqL0{Z=f_h#h| zK>T(&@&kP2;Q34W^QiuCTklwT%qQac*A?%ltI}ZZ&RJ&fu1__%9KHH>I^bXN^VjQ?I;L>e zP{Gk3u8OISnJSbH@z(Pjw!=z9~&f;1%#((&SgAvq^EKcBd+dxmi(e)-c(0Ce4 z!xCl?KPddY@(k%$y)918ALk+T(_F`Sbk`x@%&6XLCk*`?89jw_lF|Lxx9&knAb*ON{RyNKM?VM-RxnZ74W}~?jL>yf`0Jpo;z|sD_|w7GtHZj>1D zQ}HYbFV(wCAp-XIq+Xxx3D}<>bDp-8F~JXVuLNkd>*4&;^V*v%XJ8#Z-lsy-VE&cw z@<9SQL^+MlQx1Ms-uMNapmSh69OV`jdQ{L zI!D*_o6tX*w<#@)`2ACHU@5Bqh16;F#w!!|*VThJmS<@@vDn?FcMJDG{z}xo$sYPQ z3XOPMUqf6QSM%HEKAitcY}Pd>e{hZQz65I#!4Eqh1?YYs9mRf6#pb*}G=-T(zv2mR9kbeF|f7PYG6e0R5A5t`YvbeNXxq;kg#f$kfP1RDaP}zE(9hezN>_8uV|N z@e~|r20g(ME@p~u$P1khH!56*=jWVLAC<%N60E`DtIr62kS!KtcY)u9;>cg4Kd685 zL-z~k>;2fDt8z}+p#NoZH+iKF{$G;zjB+5@-&NnYEr*W~{BV)-0ff)vSnk(fY^jj% z&TV_U@HC-3VbEP~Q^3U>Sc_z35Nh64mYtj9mNem1`s3#S^P zjyRBoWyF}+3PRqg#5d(9nj@W>S0F|M@ux4FUCDR&{$+bgyv&sdemL|oO;~t;4z}Jb zb}~!16PMV=JAVuMHzJ?r_~}3$`2Z#^vkLL=x$nHOh#$0T^f-RV)5F;XD-!8N`>Ed%Cn zxQ>kcjTD%|1m#|>D#AX81WK}sZ1BIg3ds9n!G3mRG(JW3hfGJ)EDKYje~Ig?h2{k7 z6ejOn^`k#=8dG!GY9*)2#ZxxDwaS5in|v~b65#n^3yn?04{OSMXiIeneqi9end1>Z zjXk@1$5#;MZ&-B(agKriO)BHr>iwI6M=EC&?T7Er=hbG4_~FdNs&(E8f*)j0JbyU{ z{TuRL9O>GZNLT@bUE~7rZ|)SW2sO-aSK=D*K=lVYverh#5B!swJ-q#d{RLR&Oq~rQ zVUhNKolV4BF#1`oIBv*4?^z=a^4%W8Pa1ZALHt*suc40W4_Ml9Mb%S8{b4tQ(;0iv zFDTNmKV`43!G$D(Ro!8Jdt+4j(vI#aT)n=u>Mz(26?xOLwCa|~sWO^sz{2Xq)FM#-A*l{2CgZ;$)L%LF> zh6Dc=^S$4&f_(SMOq-ILf@+NCVEIiAn17`v>?V%%53$RUIO2bDjx2wdX5#*1V5PsP z4fl-h9*!f%;C~+_Ree%uZNVAY^1_}Rt;L*nogPH@M{yPV*ld~$UmoZUC8s7gZb^B61QJH4Rbtv4oe|s75_|L=huT6?)FM1LDurFtk ztm#!RHb1oBy2_S``CYvrLJQ}v;Vtj3SkN!n_@45A5BGOY<|7$&f7iv8#k^P}?w|8{ zk21eodt8IFl+%Mesv- zpPYQ~>?n3;-vzO3Vc6f@ggLlFKS)!rk#Y<8-%j?ma^yc->V3?A!}Id0`GMD>2!7y< z?!%~nvj?<0Xjkt;AM8%cZL<%v@k>fwdY+JfUc7VoHYfP+5er6-$M8IDGh+&y3&9V+ z8_``{{1}iazJ2r7JlO5B`p*`6kX)ljrbwc>TjAvt93{FN1z?SdZ1{#@SjtDzQUl9rmY024mJE;Kzr$3K{qzehZqDyNBYpCd(l< zCS8IbqGLOk&7j_zkZ4{zHVS-nBrhv`ejGclq2Ce+=a=&2f-K^PCov=VF8KT>LTZf6 z|M0_1rlD05#MQ^n51%^${Z_ZtAD@5W*N^2$wE3A*0RM)xETQ~&zLdyzl>b&WJ$1@Q znTY=r-{(-=1l~@0Y?wX`{`b+L?oQ2;YV6*xvr;)Qk1P2&mB??1pU3(r+EM;JT1K$( zLObz%C)-}ETnpl^pq2T<;D1*S{!BRhyakWDE8&gdH5mRvFkl(pe@ItBApb0V=2`mYWN9ntZC{BtM-+gULr{K=jUM#+;cxU83qem2tO}1& z{ed}hZ*lGx!4EeSjVb&}dNHzZX&x(UnOKSPnRYSAJ6$^}D(?sS!SbTz?f?7x%Y#!9 zKV+ppy!4@si2s>BTXyhV%)#gc=py!-cH&iMcTwwtexXfq(FKQl;I&3+4B|JgUsO2y z{a-i;3MeWO&u7bDxwT3I^CErYZ*ehx#&R!)KMR3=$Og7RKX>rIhh*4S72y3pkWSk` z{E*NQCc%A@;D_DwwG=l$j>23PiuGYQzm$<*hufha#N$TZ&=JUowY^EWB@FhL@Y&%j zvcK6w3J1Px68xb4@hYvt&MAzy`n?P<+ZeZSv^97x-On~!$ z;?lb!bpA_h*LGZgMDPRu{y}$V&<~bUIb1hA*@Afe!FKFC?EmefN}R%;)Ihyh)xFkq8mHnWk)Mb2YoNZc@)GRN zeL~;?;s;mDr>l}j2!7Cd#V@+{s~WTRXMRap4)c8kIG(3|h5S{-?}qQ-*OL7&R?H%P z!1Gy9{$>QTaKH3R?7#cx+~+v$BFHyCSF1W(3H??(c$j*Y;QVfkWogIIPhiP6r4_y4 z{@2+-?T+q$CKZ0E%1Gk=`hQHlc|4Wf7x$l8hA3o+5*d<;B1yR%G?cto={sp7jH$ z|8o0Y@t6Sr>zXF}^kD$hqu)0)=D<9zy`#*1P2hhtl7}+b!2XswzU#4q)L@UtYwK6R{%SJ1FyJ&@ zEeQS3LTU=N1yKLZvX<91$bq@*jpsRBryFseJdvpx@W0Nbv^iz4e))?;Vs|OQ4}k`Z z{p#?3D0w1yU>5qX2969(2OkIhujAKpSI`gsnmqCl`Tw@4gPKS`t?s31v1RLvuEmB)nBA05w*lxEuInrWZh(H@F4+GM>R;mN)TL*D-;duxVaJKLg#FFe zH(r(6nTmN@vSIzUt$2a^Lcl)I4`zGM^u>e!6@F*Ub`s*B6uOl$6#v|5`(mCeK=|)m zx?hv;`Qe@WvXb6#IKQM_A07liKcxQZo0NK}2VI-yAh|;P<)F04*bMt`WOvLhBSjDEYhOmOBYwy%&+bnXA^1Tf zBk7V9)S0=v-b?&^2K{%s-~V_Pr{Lrt>_4rc|4MbCK9B+8&m$wp3=lu$GLa5{S0MO7 z-FCfif9eRff8UmhM4114q$`7VG>MGcJ9CAk{!GGG3j$k_e)^O2iXQ4;%Kc^Ove|xP}(tR2@N6FDE0dzx}gVKr){_uWxqN?muupi-b<0)Uke$qK~^1f&h z{P4Y)_{~k0 z;0NV9PWuNS-@Gw3GtdG3R?^8GA?N%dPt(_>{c?Q})9u^gi}=C6lK&Lquf4L0yEe## z{XLM#ynh+`uS^Eq$3pE#uvc$&b&j?I|Jv{4)`WRn){JhljIe*~{#~kwAGYnRm~T2n z@Iz6$^OKWs?vJrj2jSgh?Cb2Nk47mZoa^Z^-{9y{P4M1H^;tG&h@W-)4rv^Qe#orGSlSCv4{8|M;xPyI^ZDCXp0{8> zX*`361&0ZKkaF#;V`=Hb_`mFw+JO93&>a`Ap@kM~_4?01UC4*2Io!`%f%{WJaKZ=i zLvr>0B%|vDKdc&E6{%pSVyP{;t9_7%%3cao5&V&gGw!+glEJYRyVRPDqx-v*S)2pi z-yZqAOes|2{<-w{m_&K#2)M7q7xLlz&RTBf1mS zuft7V7~XtL*q_S3Yz6;&f7G70UJc$~psr`G4^r_r+ccd0g9h-X%wsRA!GCfv zQFbAIkndePcvYR?htJkdl~kBt$6pgW)0t9@7b-{Fxx@S2x-%Nz9z*_WRG%eS82opB zMrs}M-$E0$=YmWLe!y>R%PgO$!m>^YY<>p*H`)B9nl|VO#$I`Ik!(RvACYf~;)h|& zz+EW+c&J}DOe2Bdho3YBR`if>wq=@5oCf|4AJgthhy0bCNXYaz=-+t#&-~XM#4kxp z7q+ANL#M>m1LKDY`+L0Wf)5Swb|uY)R;1&#%52$f=m`DKJ;GUSFpo=^b;JK0#812Y zHA)aaXlTe>UVcaL!{w9Q=g*shZb|Q(bwM-qQC00&vZa!6<8YbR=Z$NyZ_nDYL?C`M z?54P(`ok~IuXpCe34Q?8Xm>Bf-NG7)FXW*AIecLAQR6}iZt$GH@W5mven5QnrZU){ zV6wqCRDWQPIx)y7Nz@;F>W?%mCJtbO3rCp8L4V}a_IXTRc^KEJXiR$x{#V@KbM_U8 zU-hiM&0U1Q|C!*_nzRBD|EKX*;XmGxG11$uxx>*(7%nKrxfS&Lhb7I-xp;>0msJYN zNdIs@viLQsKcuf6AwT#;tltsZ-1@yg1-ouypLhIXD;{Guxx6R>_G5R08V&b=f(c&p z7xsTuJNh?@-v{OcZpcg!{IJAmS0dI&ndrTT{laW$?OQ59Kd8$VD+Bw9TQnx7j9HTL;6rPjO0fTTSU)x)e)w&B zSfEap;D?;-RE6_}6iiXaUPXQqIREq&Pp~K4(W_w`>^TFvL zaevjtMVP*U^SbNx@N_4f*8@}U+i2lDFJxVPGXv-Ou%~g|3poGly9Yeb`Pcoy=C_he z@I$TKWC*%197kSRG{Su$b$BBx6Ydj6?9P`+xK9RBD4RrK|N9?Y7DB*9F6J1) z555(-=5SwP1CC~!;l9LJGq`?rJfYy6lr@_w@V~y>P7Y7P{o5KZF{=RUy|`QC{8kBm z_-mzKh@Ndc+fgdP;M8CN?0^R@ni{{<3y@>m3 z-d?P57AIp4+0`WvZzO@vR*JC_&Yeu@&tVJj;|}|}O+SMFDQ-%#NB-y8kC#ELqlEvy zwQFn9CIXhh{u-bU4*9r)*c1F9 zh4KBG0DmcJP=8Se{AHoWrEGTar}VEcsI7xPebTl+6Y;~iMqdTuhX=~X*PpZy{9sfc zbV~vJbaWLN2Y=4OH|Bu+Kc8sNvKQFjwI`p~O?D9caHy>} zuau37y>s4rH30HZeWCAv#wVxZd&Vl{AfCW74y@>+_#>)3(hv1NGzT%-&t?<$r}*;8 zr#I-_-$)r!fIKp;arXMIa+rJLRO4}@BniKH+W!u!Kd@z-m_hvTTGLzqDi`6upP7mo z;NZ9UF7GWn5Bhz)x_0Ot=zlpleBWwZC*!v%ik}}q{PnqxpAqG6AGO^1^wEjnhY=kM)PLohdtO7lJa@~Db_C+-ZrVWZR*0w5rQD8jL;P*W{DOq?_h;Sza)lls_~Gw` zj?XAwr{B|(WDW6pq>)EQCdBih>v_>j5YImsy(ke3_Cuqf-Tn#e$Ib9a&38?LAFe&3 zVM6!Jd^C+@cstZPN_n&Cev$BDD~ldIlNwCT_aa{qtl$2^TJH<2cRV_*vP+NP2aOXA zfk_l9#&ys~A9w{jr8qKeQcS^r)8{<(0sj4-{zVA!1N%!-_y_p@htxf{+_j2 zZkbLZW8Z7!EyI5%VQCl6-q{QMORAgslLGVGyH9`0K=q^BT~AsN|5Ypo861}*_`!fT zqq43z1>;E}S2!5L`=QT&mWo6EdD^HuLiI>Tv!8M4Ljk>GY>p#$FKC)6nOSg>gskMWWS>Gb6;S+=-jWBEf)xW*dIF0 z;sv}M8SSI+5qR0MU)c2d&7CtlQ}MkY=T7(8wqmsTALdd0a7t#&Cd3bA;_j2a#l-!`%~Tw! z3;g?fZt4O(=m#Gu-uf$7NXFmyw&gV&!u!82^E=ew{up99{07w@2F$a#<8~1I5X!2k z;}7{~p|CIHhv0ud**39g!2FGS+|ImzO~^Ro_I(KONm{5a8SOD;^a{jwX0V)-bw`xu=c{G6M`)Z`4`!goNvliuFWUcO-eYPg}LHK-B zp6hoKHgaD3!?`mxc>O7=zq0lfP7ggUGne;$fqg!w)t~{|NWbOPNf$7r{ZaCUF1KjxLAe#j0t|Y zeCf&GO0y9xeDI}b+_ z{E!qld(Ss}0DGt8^6r8;^g)KJo=O3~`InX1z~>4DKW_MY4b5-e?YwIS^-u7opW;yx zC+ttOiR%xkfsFC8s&(?oBw<3`rgyJF{&~0d<)a70V2)*`kcU3RPm_o5pGNstUlOy- zavi}B-v=_x_N=C2)(_sq(cNmr7j{3mbrR;c57+$5*#&*n{BLj72|)aI<)3sOVzK!P83CuDd{LcaLA|IbH~kS`v3JNn!g^2y0OR~spiPtJWvTdV-~x6Inojp`5I z8}`XJ?j!i&tV?Hc6y&SF>Rys^gnV@uZ-CMgZ?8c{+4m0 z>gMqKGvAxaa6CY)$I6bsd<*B-h5c@=In;|z*eFk?!{51kzpwRSs3+ANu9rOy`~S~c z!4~a5y~O@vdTD|myhBDFg+RTk@EEg`57euKYHpe#{UCXd6K^}zv(DXkCyDHD`^AO9 zY_Pxf;s`gV@#X*he*K@^)|b!1J8O3|WqRQJHa(^HKMneQZxVaxaqSw6z0G$8*?-OT z`7N68`IX1_PnK5_{GgM~WVW zt3{&oM_#XY&E7-YU*rivOS+c>*p9wBhuE8B?9Qa0XCCCA&xR)FUecl9GA(BIFX8+r zG<9;I^M8l;`?_;1!4Erzm-BAKkuk@oKMRYwlQGRrdl_mW@066n5o@qx7`LQynu)>w zC-iJ1rNaIf%nnP|>J$8+DlfPBaa;;kYsn_RY|KOu)b|%AddGp!4FnpXHVXPdNHHkq>l&Gi|xCzpFDlgZ?XXuQW~H(-iFcyN|90Fn{voHT4sH24wsS zOZ&_O_}}-t?%gYg^{xY%^{aIRKUgr|%lnrKx(AI@Z~y*BJ&`Ch_(7*; zEd%^pIpt343-OmgSEK{thbti`CKuHSe)tg{p<4vJ%|Y?plMUyWJ;g&x2Kq@Z1#X`H z3jHMAH#|yE{@9`RH9v~~s%Q5~mWUDjAp11T@v6lLV{T#dc5Py7z;D;3wjg>Y%y#IUk?n<0nEB?V#NMw`? z=Jxx#?CgFqg14$z2Kd4HUwp9xXuaG$V=s0k;s3qAHnvTt{08((r9{4e9}WFd{9mtf zq(VQ{qn-m7o+IAuTf|YSYM@J{E^js z-(dc;OTYWLx(69oPj9n(0_*$bO1(eBdQP2`LPt%4A5O3<2N%V_yDN3x_gSI;YNPwE z-Aj0XL4&#I{#wKUj+-rhR)_QRKqfyv6TbgUPz>jet;GGq7k61t=L5{2biMRWhf{?+n^lP3ubK9aB;%7dF zy>;c#&$)DYcYYA`bBZNae?|PzPfDqng7udb7T7|J34Y*Idv*V_4(LXiE~_j;{_3M* z#)suGczVx+e z1g4Z%$`prjL7A2?6C(<~(ik6r{MV7r4VO|f zrcJrZE(Lj~a-m z2f_dDf3VN(FZ44hm#osv#5W8(U5obVFbYsXI>k37(l;t@Q?Pq zFW`T}MknTfLqGL&`aYRt$cNRbY#o}1_{B^1yJ0^3{(Ixa1h0q@_V*&SgSi{}uPhRL z>H|VXu;aVAmP=Aoap`~e+dXc#Vtr(DvKGWo>^!oJDF50%mSdq-Oz^{tq!M*+s5`|Q z>utfe55v3BvPX~ALEm!s({OQk|EMfslL8;aZ|0wA!qEGxdrYbx4d)a5Kw1c}@&^5p zAD{n(kv7zSL5=??X8^|@MLRu)_XiiUHD`~2{ZS5hKH-7SZ~8I*JY0a_2Zl#XXQ5vn z)AaV*wTF>}oj66}kOKXJLp=>=>VpA1o4dos3gTCCEz4ohKrJ|8G#>6zCZtk`gbz8zGY086YFj16%NdN zuEHdS8JcUGV7?>gM!r4h2?`Yj9)^LQz_Q>^2jT}4+4*g^VgE}MwjWU>6Z~Lf^`u!C z^38WejWVP_ukik}ZgJNOh^KE9ZI%N)gMPr>;C!$@T3uC1q+hMgmHOE8@X`O`UlTo1 zzrVoSAIim|0!&6Qy6QJQcR^3Vpx5;BD(EThsVZMapZ}YtLIr((COyl(%pXMkL73t4 z_Z2wz)0Zb^bfA6|wYBr#L_7)4eD-#jsjC`m^X0KY^@pzw^^xfBCv6iH{FYC||LLR8 z?vp{kAPn0=p1=EC4h-XtJVL^)rWAbJ74AAY*#FEDz6Ml(NG@8l9TOz@p_9#_ zIuQKtl*kBs)^H;Bs@8zr1@uQx-=;fu3J&AKx5|u!!2aYU#q|)sW*GL`T5Klj58o^( zJ!~+)F6vZ*oCxUmm!nGD_wYgg{Iuv;F3jP%loTzc0rr0``$H$C0hs{@Nah&Z7Ro&2dfB+7iV5^>wjX zq#X20D^nN0d;q-?W0Z$81@ug17wl!qAs;sRe10$*&VQ2Nur`{%#PD8`^-B=J4{cvI zCg-+Mv5oA54oZn5nBaq|EBik#NhJI#Qjxw z^aGiTOv0{4CNOMUuf}s%qFJ74jo{34s?DT6n4@BIz#RFX>{_OA=n2(y*3FebPq^b2C2<`5@50WsXyktnH*qkO(#J5u4gJqscP66xgR^^YBdR~#VNI)ZdPCSB zL(lY7Ea(Rr;x+BopnsC@xVmC}It5STzqr;4`rn;86`mRp|D5eBl|}sUX}v5dViV!N zPTgJ2zMG8T3cj&E(eR&7pro{oC`$5Px9@zIdYiZSa*?`8895 zAL@I=1gOBjmtJyBuxln`C)8iRn~NR6dA0?YHi{18TNy0oIADEfRL;a0tXBpc-Ni!i z!^5KX%bm3;7@Lnsoh`$HlUr$H;U>3;zZ!8l6k?okGlnivG);7c43WVe7gNT?OJ~#el%=f-4j@^9m+1-4C~ci$DVj7 zL)0I>txNno1oJocF%<^z8&WWCHugr-yaAl=lXtWo_+PI_-BoPx{kyaeucGfyzQ+{( zMugypOU=nF+|OZdbX+s}59ohA_{s`*fPO#OB7y1){Cnd97P$<+-`tBqPgD5)GW;EM zRQ}UH7sB>o)i#5KS-SHxPfu0jdD=!+{osFd@HFEKU*H}dyJO1+`*-w@oEzdlnW|9o zeo=xSV(tDOG6B8(JJ+CtW_7>^Y&0sjk)Ghl#eAvrFjwe?&O3InpDWQ{-Xi-cc+q*X zh>qX~)dvj2d5~{D`lNRL4CwWrW_QgBfu28UT6M+~^!$ophqm~`dK#|ie#8$o1<$=_ z)d_xBI_@Gh3!kSYZPFoOG=e>ldX>%(^8{XS>)~ zqIF{bO++aC9M&)=^WkNY80eo2_5c1sD~E)?9`ImrUV`~`0~at4z+GuoD&H_}K3#EZ4(`ve)m-Oaus-K} zewCgE!4F)%+wKW{O2wosHb-6r{$;BW^|~NP#g{TWo*fAr!I|RX&NaaO%@AWnMfGF5 zS7g(i@5KG%_($C`73O8=DAe;u!@LYpL5tFDFi*pZL)T#v>Ol<)>15T;gKhG(=tXhHf zW(V)y;58)pp@!i|g$?vg`wz^7I*P#igFACiPs96zC(I5qiEAX|H4o2eNP++U=cqV_ z@_*Ok)HjE#5&R%nkmj~eVHo>nT5y;50tM6i`o>QI^n-5iJq(`%|As9W_@n%z=kc7V z3t)fCHIrw${0M$v;gdM4nn}TSwoBRa!~BiIbRDm7@V{4nU3;Pm`RBaNsywKFB6oDr z0rgL8y!-x)iHoqmTS^wjLW3mimf+3k_FXmjKdz(rW#Hd_hT3R#sQ(TWtj=mf{KQXt z)(^!`v6nyc{QeI=CPaO|I`EXEu{?z7huC*tu%Z#s4fr z`S;cBDcmUkz9ZPx>svapo=JbnLksxVda@^O7w8A8oK-ft##8Vx!>j$DBuKcGO~Q5> zus@x2KlwoTqF^$z;r~bLUXn@nme6V~Xc3 z>iadYKgFcvo9OdvRFYG_eIWS3qFjFZ@oWlaZ)<2d3;E{{#rs1_w^DIYo*v~bkjEa3 zf834gFHW4M28{6cvxX?EcxDsvzuvdx69-^k)rw&C$x@hC)lYV>O@w(?2EWZ-o`rnW zTYZ0f8~FYCzI)=r2FR`BW#F3r$FfU8@1V_X)SNqtTY?`buT3pXAm7~M+tO=KTBIk^b-zlZu#6y3jfG$Ug#4iohUMj;8Z5%9Jn|D|q5;B6anwEA(FrziZb zQ8Nk7uj&UwHB^5drBW}U{-s`t3Bz4>#QnuVy(jy~3i8$wHH@a9A1o3V`cPI)!dr$| zlA;A_unQuIOdpW{(W2=>^#_h~KT=5l;fJCqPWk(gf7aLU?5YO+{@v&x7V88G9<`j+ zwuOd-Z`;uwJp=YPaC{L*{%`Wca;Dfhf*;~HANu$d>c1=GeYZ@`lCc)H*qEUs!}vc{ z-V8}i3V!}Rd1?s!@2GTkQw6M-GXHhZ{0+emzXz0aZi33jLF(et1tG1OLB6^U?^aKa|GCXwK0Q{II!QemFEN6{<6*a`uklk3Hv*#^NXed=0&o}x!-c(>Bo{4&01IC zJ);@X>Nf$9k79kksILX_&utENRg^#Vol2|Ny-viBd<@5beusILnZlGuH}`@5+Nr0H z2l_!`gyIC0!T&ZHizo*|{B^vmKnU@}k6WpU13Cmh+%CLlZ@B~V|A$mY$uT1sXY(QU z=W!``#O=7Oz1lE8cHo&T53En43)CG&_Ul4vbKocVfv+|@=vD&cX@nO#h2i|JP~UGm z2>v&@ara#ZnPfbOETn|$4>sRX5AJc{ynOq=Zo^^qc*EwAD0sL7jqjQw8*Dmd;L$((9n>ur+zo& zFvve2mk6g*3?0DP3g&O3`1{x1TPBULe^;+*HhkkD;zx5^u}y}PBuvcZa&N-%8vKc~ z0||%vZ(Q-(?X(|Me0LJ(7H_bh6uR*nDE_Cv$|UJ_h~Nje+mrk5!MyZ&74nc0%xm@Z zFO*w>{;Qv^`vz<;L0{r2{Dmj1?>Zk8hxlVbwBP3HUVHRo~66R0sAL%yd_{B_HQ^KQ{)mq!4FC)it&%X!#mXsvO}*U2C!TD zw+>B2QShm%uI`6Npnha^kz+g9kGF~AEo48HbH56*juQOvIx3TKKH41)Fof&%y>uYtrdz)Z=@0Kgm@zw-CoIA>WaUqk8seN&m>ETVr zbSv+xaYNqeZ`j|1d7$4<8hk=R{9sUczY6g~Xz~V)*&4C`zO)iIHe^#VF}-({v_`GC z#wKswoGny5Yt76f9Q1=l5}yyF_a8o7&W}Rp*Jva7X=^lLe?c0*e`T<@Vzqo)OeQd| zxscn)ogLmY`p4?HhYJ2TYn;sr-5)INTP^)y|F)5H-nTFi{J?6!D)+e*^Oge%LPZyW%zEuO=C2UTMMk zEh!D+ilIxxZ~3XF7`wt8kAPy{UvPgmyzBlu4eOtuRh|?&MexH*%anf?B1W)Y*6Wgi z5I@_tD#dbw|Gj%cag}yU63$e8${6K;^aMg0(ES}quklm=6TuH5d)xikq3@$x)F-CP z7Ty7!4kR7P9l$Ah_WBo~|7!Gijzx5cWIbnaUoqlS&;r*k#VsQtu zkC3op-{Lot<5WD_HlW=N`k!xy6#rZR|25b((;*N0f9Q>=w(=Ok4{3%p_qC(o-9pD} zleQ(*_{%|u>!+aqYTB)@%A@1NXuO;R$0SbuSG zWb{0DD|W5zTf|LxFQInky(>TTLu$*|zaoMEO?xAwMF;k`sP5o^^8erZdZ%4#2!3e4 z`Zit&@>gnh4qCDjF#mJDM41mdPZQSp@c%eW!f^@x!(Fy~7q?Unu`S z{rkaBcLl|EQL!9R`uSjppS$gs8(Wf7@LgpLr%s=3#olw7e%b_|pVsfCe-qYYhGGrm za)KW`8l2`blR-aNz0I5f@>hG~-?bISlkqXnNT*5KWc;qN{2coGCrtW+5kFBim*2Xi z6Y;;&?SLQW;r*j4I?s>o(xPC_SB5gjUk>0Te0v6iGa0WfHhyXezyE%QOV6CK~S z`7pr`cef~QoztnpzL}M2c|gDM_Dj=})P@k#wxCbpOyf z&O-W?;D@_)i{BUF-9oSDcJBki2e8)9Azk*N6kJDRP2;l)30L5s4o3GMy(@djBCJn} zWm;)HNbmz)Css^N9KbSzt2E?pld(>>6eeZp-w23}=SYS32YYp!`cVGn*xz+!)IT~J zpew}KNASZ9-@voBMP%#`$VImFCt+%jA2vrq-pTI38+%{)ch0n&xa|S=f8t=T2kKus z8dM$g%Z#|cSR*ud{)H*-Urp^F|CczMinot`@$PhP#rR$JQBeIMJ?pWV z57=MC7s2nlXb66&xWubb6E=e79raB!g!+;DmY8A2dNSUrd(YTW4c-quOnu-2@dp=W zH3I3U!vbH=u{CKEeK*uhgBTS0?!3jzb8^1^lnVpQ+%O^lDu5n_9P#=?Gq-duP4@;_zMlk_=q1 zep7E>=LoF-WL!Oz$wcr&e0cGi-eMJ&dXAL4S`7Mj5%tKupeLwS-j%EgdEJG;=F?jt z{-m|;fG0Mg|3GA_QHz7%hn_FBdecCe@g>_@wPL(+L4!4LCm-8;*Ns93RI$Ad3k1K7!`o&l*m=)Ve;d@&2}4@xjG za=XL&-|>e=5PyUihthWLA^5?iVOF6=Z7J2Y)l3u)@lw%TBAYWgb3;KnZ&Rq)__+Q!h zy8A2e`|Y`^y^iWP-Niz}Mumj^?PXH)pJPtN3O;eq{IhDs&weHq$%B4>+icm?$! z_Kbx}#1AFEUmQjJP_+4aQ7;d{4@#t@E!5dQjDh)Vw-?cvH#vMelr9r-me) zbd2{E;{On`2otJ5r0sga?D?Ph5yuT9g)Bfnh?Qn?wZr>IyDMBmG~x$vy|$hEvM-bI zgS_OqBXECwlljH{81|2?;L7{&8;AZkzhdP|+w3TspEE-}J~st%=GPKe2GAd=im&!A zKOVsQe2W=-z<#dHP;IKfem2feb4iyG{J>^t5IsCW!k!$+bel4%!EHGr+3uVN{fZKk z-O)BGzL)v-@lm)xHT?a4qWsI(Pv1PJRSACh)9Lkf@5L&NPDta%J@CIu?r%b{--Foi zfa2PN#xPe%b6ovB+~1|ABN9>lSWszgJ@Y-m4~AEm+-Yyay%yZndlL9p;bCCsS|IdM zpJQlDg#L|Z1M!Ne|213SND1PHzFz*b@5~7MQ@i^tAsyZ;jgveRQg(R+d&W{w_UcC! z7U}aO;YS(p{@@;?f8f9Fjm-KZe&|+PH@*0s;0LE2ob;)1?mPFbPWDr%*uTk=9X<&p z{BI*?fcTqgEaCaNj<4W91q?(s{=)jLyRHuvIuZ2;>map8A>d{)%HPw6LIyCpvqKe| z0x7sz+Up{T(C4-P7(y$4|a#^09GGH*vRwlwW6 zU;_GuE~&8YY4E@CfAccpAbyy<88n9YK|#LBTEms#hrd~jUY(U>Y({J~z#%RPyDGQ4 zEgbZNik3csCBVP5X0%68|HM?)$OP)2cxqmuu|Y@Ne?1Ov-czNim~tj-@O`^hJlN8L zGz0qm2TG$w)i6Kyu?nN78pKa*>@~Yl{&nqY{Oe8s;fHCN%F}J|UhhQr{g3tVUN7g6 z(~1`GZz4Qts{{3*SW%re7KqX+=6LZDKTG@e+3rQ^Sto+yHCefcm3P*Hd6p$oD$c%OY_9GA{98|>hVtJ{C%%fH`ooC6^AU5XvHZXI`_e$FBe;Qc)|Xh4^{z#fuWCf9DlDgN;=@vA*c~(*RcRztLn9 zM;&;7(B#?WmKW(TKi0q|q0oVhtCd_IX8`-#QWs7}@w+_@ePm-5!4In@74a?pFgH42 zi7E;2|CW03&4dh4aWAGz@aaRmJpY6S9AT2@lBBfVo?7iN8Mp-`2By+$lgW2zw~xzIbL33{aY4gyOh~M ztdqg;#J2O$N28zc&dH_*-hB*gjT3~+N&ImX>BN%n(`C;U}#rz z^ajM;1Cw-Lp8E}8XACNyD}a7sB{scb0QCE;Z%Mt#{)=ZjrcnLOIeTuvIfdYd%Cpjx z*aWB_-L1OQWJAWnX-T_`K|d(U`L`tR6b0WI&#yNF=damOWe4Ji{O&`&nHz-ttaGF` zT}>xr>bCR}<-#gDR7M72cESt zkD1-Am|sZM+ruz_@`%i@3rUcFmTDY-^d9`;h=FW)E7%{`trRtM|CJu!6ukEW!4FyC z%k;9~uNBqFsRAxHJ7&>meUD^G##RD%hWo$e(?v{$QNd?8eYR@Pne@ z`Ew%Rx7oHjM0^h!0lj~1!}C8Wc#w+p%N>_mG2tyq(=B_`%F2p-ZTm;D_EK z%>*3ySNiO#jx*>7CClee*(VR+yMBs4m$o3|8V<1*$p8JjFT9HKXPY_{3e-;${P0me zl%@mn&xThQeh*GIVzbwb7Ig=y_=s&)@v=9}!TZ^Fy&L?m_lu8r5I-2%>)oS`Cir3B zQ1Qcy10*a#V*TmOb2YfNzwXsSvl0A(EuT;D~&YwXZ{Qo~5S_70n9C$1wW43+lan6~mM$Ukq?h72nH8N|A1_UuqHgmZDB$Q8|h6nJ)!jN*@d`?vkM z^Mvr9Dqjy@GKYM#N4SSb3-nu^^>Z^~e+GHBi95G$Ks=p{zceShBIKN@Ee~KkQM|69(e?MI`31{~Bs6CQejh&MTv=M;yEh;nxR9L_C zbyCu88^I46litCXhN+l@$a*7hAk2?Fpyc}S2?e(v?YY0IO2QLE8k;#G{#^Jld)XbaQ)~o3C@U`7AA$LkEP@t89`tB-9rfR& zz6liGl1$j2TJ0f~E$_)#zsOyU60;;s|M5OnSvYs9=1Rs^Q2$*McRRBg;_vdOtsEa= z|E6Tfi-R;o{CK42m*_k-75n<-wEUPPTE z;)lIc!8F)@f*%y+SVB7HTd?{oS|88z_QU(n83kM0`Y;axB`gi%BQ^>c=?^j*tJ@b8Dg)TAqrN6vA+Nl`5&<3eqRuKIjR!t44MGr3{^%>BI$ z=3xIasQWp&*$IC5v`1L<4*2bl!PzX^K)-LnzU!a?oL|P}9kWe0$hgTraVca!abp4c z$bMK(Y$E4wCiuZ-cYdcS)PMDS^EU=mN!T)o^Yx(b!cg`Ut$)}6-uYc%=^3mq89m5{ z_#xJ{QGXFR;Qek6_uw<=y|9fs-ix3o;Je{I&+7pGcc&qa_~D4~niHx& zv`C+Ie-cF4-#Zq@Mt8_JGo_p#Yli+Se`(z&EobO+cz5F@JLIzzUn|?A`=i2wVFmRs z9m?U$d$~sNLs_+YsLiiIux~+Xh3N<;_vz%qJ^d=opH*C_8RGd80k;Y=*iYz-Olfp~ zg}=-m7|9{{Vbh*;JPG1wS9mdc4c-s+wKC1``9;D7deq_sjB2o0_XnwCaDVP9*;4Qu z)`zqR^aY+E_~Ebi4AlbiSBJ~>A9V$Q{x`7MXBX)Ad-`+ab!Qv#5}U2FDE}kcX)cED z@5b{TQGbgFesB?})|i3$&-vl^pBr3*^E-8Cg$(>#Gg+Ox;|v8S$&PxW{-x>a7d^;- zOowIfAsZ0(XLcndQW@S~Xr{hClr)os$=~EXeme#BPvVnm3-n(tvMO#v{2*tZsEhJn zKjJe?GP($U`1jOzH6<$rd)$8Zs|L(}wx1ke-7gIK7x(=tvY=xsmWxwr0sm>b`YQbo zte-#p)%J`V!4EYbpF}M|y>_c+bn-svS8m)FP#gKH4=Z`AMN<#;AnTFa(Z|7mGl_=T zA^(lt_~EL-MexJHA&m@6l&@aP%v6ScE!Cf)!CQD+u~xAkZM1NH9s2z|k|2JFQTs+Q z1^fFD|9aK*Km4F`w`-ds_|C8j|9Y_VFr1N^U36a9Uj5}3c?Unyvcf&cBk^&911b@%%0 z)&~32wUDm)6HU|~lJnC1UMLM?#ACs8e-k&)8E(-e8FIL*4_kTO! zfk`H?KNW#ZADm(Tr|axj>Jtclm=4yxMg#G)#$Ek@K&S&<@j4b&{}1NJD%1`(fd9oi z>>Vn>{vHm9@*{q@hm(z_-UR)RA7oOx&(K5uN-RM9>KGZ`-=Sz;ssjB!+fA3>*?HBN zLz*9%9zH*AB{324L-&_^cE8>b{JpX2@%ob^X!!Lwr| zJR!(k9`OU0;dmPAU%HsCmTCEvupjGBS?4b2K;2j%U8mKIjIEtkdaMuJD&C_Xc*LH9 zf0R?=zXZR(V@F&g`u!>I9<(m85bJgM6#uQk`$rPay8Y=pA^)70d&&alW|S#9V7<`) zOb*SFl7#&au-g2UANHR!_jNzdfB1o9ST;Vkk&4-B#xYmJ`wLbRj0KL+f5o%2K&TA* zsJRZhd}Idu+Y#gyiuj@aN4NLf5}}_iY0FHbfqLyttbDZ^`jyjnFEdDdhy1h6iO6eE z5Bd_ZTzees-y}6)E8^#VR~b$AWP%?Gw8@$(Fh9p$R%G@E8aVEjo=54Z;E?`pN(L;eDT)>!2fz(F4iy20o?)p;fyrK zWPEHe$x{LDpSj!5{1agR+qCIEX^0T~F!4bCq^2~?tu(Z$f9^!VEbp)zaz09t8q)osjuBSBRGxI z`Gvdv&_{QmFc#GxXy;Q|OW^)@e(TbIPMz?d*f}@Zl9VbeuBgab2l}7G4$bTvhkgnJ zPAYvL_}>k2Jq6@{BIm~UBmZ;Lq#$phh~S4qg`2LA-iNxzoKScp=#S2y&bH#b209Vj zJ?w*!&+_S?RU8KUJ9NMIJmQCex0SjQas)rzqMeAqfVWMQv-JMJ9N0KT&3!GP-w%j> z;_$o|@}<>ZI=aCB3g!D2qWqoU^ih!yj|hISkfJT>%A$ zNG;6nUn8z;7r~D75310$gyN4M+&>?#{Ad2i>wt?(me4e*)#8}EVC=KH& z7Pn5!=|LQ>CPUSS_-9b7ix7Np`k ztQpMhK*z-Y?y`gstnd2l`WDq6y5nS67bf}tmp?c)pQ-T?{4Wm;3$GXSOZ7#yeaWNt zVO#bb6=H>Y(C)gY@;e~@bpCaobr!zAP+rs5({uzsEc6V|pMm*xEMtsLNWY(RCTb~V zODnePrO;C;?tV;R?p86eRQC2i&^cMe z+>3|)4JpRomaL#(nD+^GMBhKFyd)Iy!^prR{fiq!{I18Y)p_?l2`lVsydx}DgQpBt z*N#E|r0sLjpXWh8*mH*81nH-}9z{B%{;x2)lgvfWiTEudt+AA@4BpFDJ`wB!`lI%z zPHb$@&-kf7v%MJn?-^z{PhQwR`|Mf|#19x}eQ*y0@%ht3hv&qD;J^Q)<78wU!iti= zop*$OO8v~$k`KVY%e2)`gu#9ks{(%wgZ*4FGiNWG3^= z+`2O>Fu(40T|xm@eKpqm!hro8oFCfEuxM0&xFfDM-Zx6{1K(s*ZT$qyfA})kN#{KP z?|ZyU+Zjy38$;9bB=(c=>u<`k5kHWmg5ZT4=zkagZf@a8+<#tGuj@{Mez5+ZdX+Nt zZwM9q+sP(9j8|_dH+yu6g1cr^_#TA&W4*RJ{0Z#e{Uodo@0)fX|v z=|73s)h_Fp_s>W0D%R`j#i0MaCX>RB_#tWFt$sDwPlL|-$i+Z{A5lD|Yj#8Z$Zuj+6#0+Mf+?P;{;<_Gni8Q(*x#dLPg7oUQZWy4 zxf^*fzb>_t=Fu6(RGgbz&iEtrZ)7h@s?&;r{U5d&It=@Na$Qq>qLtu>t5$n1-FQBN zW!Xd<9DzKt?8`%KOlc_Z^#3t+-ho*D-~T6+lq6+_h^(lP67>;3)w-q-uj{&;n}@9SKza~|iM=Q$~zT;ee}eGc?X zg8!srI;Oh-=il$#H^?--{a^blNvmn&I68|Z?&{@XrW)I1u_XA2AE)^Za3fVZrL`-hRSw2+Sxi-$o6s5+rJ33J!a=JOfuh5f%% zZEhlQ5I?lD>tZN=aHgs4FuFn1AAYf{F>Jv6jTEi)OEx2g`1cr}dJ51loS{FM`x^Xj z-OT%dDTrU5V9{D1tV zU9@7tF^HdT52l|)@snBp_bloVf*(#4Fp!vV-Y zU+{M@+6M7krzmGP?Bg#xT7K}GNm z%;QSYJHUwe0lT?Sh4RmDyg%y<4iNnC@$!ywCg`8smd@MB1N9>zLqX{+x8luKw) zs0bsK+|o0I_?7aoq9MwEw>1vYT%jW3x6@r;dU!y;V0h_P`eo?fP$^4Ebxa}Sr5e^f zuXj}9=j6=aB7V3#DkFsWVPO7fzL_U+Ug7=S1y#@wTC!)SoOXmc&i-G@>|_S#>cjI z6>c6F#QVPrK1cI|sWwY*BYrqKZaXlW?e#A|ELCK%g(byeZ0a^_N}wMUKY2mu73hDD ze5haw2^+@Gwz>t-!sn0jOE6f$`L{djP3*l1e%O&;dh9ynpEF3x_wIuKW%&B6iyP)| zT(BkMOQJ*Ag69$l3E}y@9MeVo@QjMCV(K|zKi0;!)iN`^SlVHudsl#e&sisQoZZ@p zoxNK3Dhl#pem*9vP z&_B6jC+p-XO%fg&Lz|%p_J3H%kCEUL~6hCgF`mg$|&jp1_f*-yHpVGB8f%#>u`H;bZJ`6ur zdQO<%F1Gc1;&gu@7OcMDg7QZbdtbao^D|hfCAhN{3IE9xl6-It^n+JaJP*l0|KwSn znVtS`$v7>`ktezPEAeH@eF}x(f1GpPgzbUfKX@#iK_H#r2d5m-Z?C}rwvQJMN`ihN z$oUcH&m-V}6J<8$FGC&KqIbOq?2p0PwifY&rX}@;@j-$gZimuI1XP0VVO!>T|A8nh z?eDDqK=3f0M7}uT1oN-%G{sX~GM%yhD1V0>!?)r9ZqX9eV@z?Gb z@bAXoON)PC{*}d}D&0>|4>GOgEJyv*i8S4rh#&ZFVrKXLGk@fgTty;3%)2wb5>BxK zdf~Y}N!L_38Zia(hm}9jKRJ>ZqO1w=Pr=OzJ=DKswd6b_KTPmL%;8|&^LvLd^Ka(o zB%uDgvaMFyt3DRrD>1L^2Kt5GQbyHCh`&zsZrfD>&!2Dbg7vH@QGb{m{%h|MJdE{* zsfp0Q{**71J2|d=AmK`XHb2Fljltc1XYE1p-?aSCN59~F9qrFgzn2Mqh`J_jZ3ORc zq)JMEjxia#zDM==&)|N%EXE|i3jA+!)ybQPAB-g%6Hxz)H-DB$+KR-#{PCO5^~O$^ ze|3#+CBb`tC3g7l!mF>)_b8mNEbavSD|6231j?URJ9peh@vopnUhToRg#EczE74MQ zRASE24=Fsh7vWpZEUp!Te!t2>@gyzi_vL6kcT+?Bed+)wVO;$*nKoh zcyC^SSqpWvF#ZHS-!+jF3;esuwXo%**)aA^F8!u8*iZ1ecl&;V{d`Y(Taw8|@Iz?# zXGST=H@}#b-P{WOR{#Is&;R%D(*KVJPf_P@XX?e~BF{(sL?{onV+e*E9}#a#aH_rM+h@Atq0@|d5k!tb{u+~YU;{Tvm} z=S93B;x{3l5!!sv?+ZVq(RT#>!T>dcFFX(Yn^{JrFTB4s{`(!7;rXTg-C8sQ&#yiE zq!H7i#J`{4)YaPo&l{ug<)f`}CSk0#LUV?aP(M2UzA)REjDHH_?>h+gQ=+n_gX#|= z(`$(@cN6sow^EJ=S3dy%w#0sVe>Miwu6n8k_K3$iQ*H-)#1Cj~yBh}QxxYPHDTni? zFS@d%x`BgZI%ql}}?C-bb^Z2TrK}Fz1cfX|(_G z_l%RVuLEI!)Q_0&%)!E zD*Rjteu#ZEdKvCJY{++Oyff@Cdv7Lp{B0!(S5G~^BY7YSpE5R(?S}i)=!J37ES&%S zdd7j==o(=Wh=#T!uYHiHYl8pdYl=$(fMR0v+PIX>dN=-@CusK1KZS zJ1{l9ERCo?n0{55c=wi!?OUGN@(JEwn!>VYE8u@08&YY=LjJk(bM>o7;6FO0{#-=$ zhjn2-tsf@|``dZ;#c^Jk|1299tiIG=i0AtL?6(5{OSX8_r~~z1?;m3$h#z{njH(eo zC_Q%MK3`7o!};t1k>yFy|1y!hdcfbkzV#>S6Zpf8iLT76;19F7e$RD*|CAciazOP5 z_CMAa@9`7$heCDQ9~IzlcOJC+i~Mbj+qotl@W*2Nv!0Q_AHQ1c;FkmcJ(mAY4DmzN zlI#R?Yf@|Gg)C+o;vG9~+}mW&9XI#_^TDm}H2b7wKhFPeA;XtgbqU>JR3l zQeKaP2!6P7!=yzbtsh&``?jeH`u*9elVuQ(;d}2XthJpd|Nc|DYt|H{p}JIaMLv9XKI(uWS2O!?QmZiA&FT~p&RS`1!5Rb3kzfZP;c)XD`^=>D`?|YY7+wZ~i zchiawr3@nYAxB6^-isCdHd~!|FzE2ZgF>!!CB@y!ppx>7}J$|YJ>`&#vK~^;X zrkOo8w(6$!xBuUN^(q*2dC)ig>>Yi}#sSdrdeBijf_`u+bZe@_sTiDX((lGD`22zq zBW?8gR^RH>bpOK-?7_mywvfO2Ywjrvyo3Enj9JtG|0_1hx$T4_37=iIR72nYO<;cq z;)m<5Iq#jG5%yE;wh?NVLdN*7g-``R{9JusI*T9pcf!@;-333GKUvdHhkk#W-_|Wi zKkc;J{YTbc!hYkVYx;d*|H9+-8^6Ycitughg7;V;|16kt*OHqI^V`=uxX|-Ix^r=n z6`nsMZExYy1i=rC57-Y}0^Vdi`hM*O@aA`2xvmc2(N@f_lN)%n#^m%k1=wGmL9-I# z*L^=Mi>fz?`h&x+Cx7+;@2W)cJmdi04SruA%mY09E`gqx9(Z_;{3$~g>>pR^Gtoew zudDceDvaQVT^ijv%fQ<+`O`NjfVZvRZQR)1i()YUa`nGaz-Fl=DOFZi>6A$lyOT|zHsy~KA zv0b=iM(~4hT1xXQ@b6F2s2vQT-#5MGdoUo3jQ2}~yNn;M#PtMRxK5+{N4dou@dH!B zzVjih1V8NW3vC0v3g%+GgK8)E->zXMO3tH$c-I|UU%^{sd{050H5u%W#X{c$-G7~; zF0H2jnZI<+wU=*KJPFI_*>SSvSPYg}7+Gio`KxmW=gx~mABdXh%2C7*A|9)?=>ENv z9aSY)PVmETnmP%~t#Md<^>{?17VJ;i9yAmQ^PkUf|LsZy{XVs0ORg*2|Hs%*^do-o z3sd^_L4xp~>~^7yhLCTPPdUlj4f!V8yLDpYkdK<<;jIaWe3ZHN_0g~3f3C?nbTPv3 zZyc&5AeTt+1LoEK6y>|N(v*~8knbA$kZwcJ#wmUVLl_XB1{A-3I+vu7YB8x)A@^#HQRte>= zRpv=iZp#EeBqx5oNdx}ZTyeZFAM)LY#U9%%=RrJBY$9m|`S5^ZJPPeUi`rqrjpE<_ zBjRzJ?u7lF(kVSS0Q2ka-#VvbSPgsZ+LZ(zmR91Kp<}i*{6!d7zxyjn;0H&k?!Sm1 zeyDsdas5m1Luh?yZ15=PTuaW)?t%F^LH4htL}MWC&AD>V6Y59IyWITlgZ;cBeZUbv z#1DykRxuF#aI8SL)GE0jD;?ok4~6-47q-4RBnJ7b%1K|{D=MI0n57iE3+L^Heb<}d ze4GV)`OWP_{o$Hk@XL#ZBrKT6Bx05>8oN%P9MK2$BT7-81E-*Wvd8aZ5EcCW;b)i< zQUBGJrLj{vGerL1>YU33MW;Ay8;u{I>itGs|EuhQ2I${V-|;sI?H|1RHS`{ue;a$i zqZ|Ex>6#aJNj)X(PkVk?KMv|WTX=_A1fbqC_&Bvp7V1HJ_wUYkhkB5u^C^x4@cbTf z-Rwp6BbTkJr`-R;4??HwOH!cTbSrmcZM*OgwqBYr_X+AzU#VZ&dxHPXqtq1Q1^b~< zVAC7``x&|IDtz`o^@nMt?EG~2oMFQ%4)gcJn81-)g;3D%r#<-Ca0TYqnPP+32RPrG zyFP*V;gh^v?$^TvKQP60mj^`+V{6TMhx7LjVp-a|92&v@@^m%S`SQl#7kPSbUxN3? zsOaZ0#NUQHv`c522!4?FpKARE{TpVZEv&}7-Ul*Cmn_6Q_!Wl%`*%3d~ z*d)G3`lZ38^IVI!3HyuAtZmB5Bx6+ew$ELlex%BrHO<=&@$)y8pjn@OJoR?*x+vTq zs^dA9sD2rg`dyZ5n&1a(da1l06P4JAkK*?(r6OEt$bhq3a~Pi&wQM*A{|{%Z{<%7^ zAH9KhCyK#-Y@Awuwjx5myJyx@P6S|7S}K)v^jfCKjg)Po!M)Q~Ho9-Kf!K7sN- zKfG#ncEkN`b38!tNd&V$knV5^$I1F7$g$XMXv82>L;6qGxvJ0{>dM zjNI4+`|A?f?||aBl0$301MI8+=FjWXB_7)_!u}e)?Ws8-P{+k<{N%y^8a~q8o(%J2 zSByXCbAtWpSr|8<{-rHOWl#OP34Z7t7927MZtlLto7{155KCL=ss9c0>u4&+%~`mk z@p%8~@A?qGe$SZLK=JGAhN7jv(?tBGCqsI!2mO=J&y{%#-XvrDJ5OQ;sr~pNlSiMr zu95IHM%`RAzm+%RBPZ(r-!stjC(oIP|5&$q#a;9S-T#~_{e9@)DAac~+Vgt|-_LZh zqs0UAVB7=CyCHu6>9za<)gKb$Eq?~O68unh|IX$J?EhuFc%g13y%2Y{N!Q2&Ts*m0ha)Tn>?fx`X+?aj3UEJpi9UKjK`#fRKB+L#%@ zwkWdActTxuw#z~QeSWoa&uzpHFK;?5h58cphb8wmy%gZz1xKIsX6Uy%x$bxi^<#-W zE~%A-eyjsj*URYO`_CEu)kFMrEsizD)`74e{rNvH&H!&`bPE*cg8%(c+ z&W?%kCD=>B# zcf6;=CAfDGPdgL&9PvBn;mk0^?Er`DU!2Cl=3`bzY0Ps-CLpG(SGBa8YT2Q{>V?!I}81g zdq-|}s{#MU{JeYg6x=^b<}D?tf2rW1;phn(f*=0g-Lb_3`Yo>&N1IkazvXL@k|%xO zf0Y-?&7`0obMnhje>d2l-a>!cA2|P@f|90tdHcWl+b+8JW?tyuINQ2hDfMm`8=E=h zYnc*@JHE{@(1ZEyf%l&7L-+5ox2=yP;k@#Orlw;V!4DGHQ0~pxVQi!GC1)G!Am;w? z*se=3KbF67i;CoQG~Q#Cw&o1?|4`G(J*fVy?<_~*BSiR5$_*#`AD~}IP;uK3RfYWv z`A*AAFu(nMB7R5Jl7utg<6{2;{-6(=Mg@q

-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 literal 0 HcmV?d00001 From de2e83ac59f2d6e23b9955d7b3cc02acc13f4bad Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Wed, 21 Aug 2024 10:30:58 -0600 Subject: [PATCH 15/32] pr response --- imap_processing/tests/spice/test_pointing_frame_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap_processing/tests/spice/test_pointing_frame_handler.py b/imap_processing/tests/spice/test_pointing_frame_handler.py index 3777b8f94..bf13705be 100644 --- a/imap_processing/tests/spice/test_pointing_frame_handler.py +++ b/imap_processing/tests/spice/test_pointing_frame_handler.py @@ -141,7 +141,7 @@ def test_create_pointing_frame(monkeypatch, kernel_path, ck_kernel): assert (kernel_path / "imap_dps.bc").exists() -def test_declination_plot(kernels, et_times): +def declination_plot(kernels, et_times): """Tests Inertial z axis and provides visualization.""" z_eclip_time = [] From 72c0f72d76b31f89bebd2c401220c02716b91533 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Wed, 21 Aug 2024 10:35:58 -0600 Subject: [PATCH 16/32] formatting --- imap_processing/tests/spice/test_pointing_frame_handler.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/imap_processing/tests/spice/test_pointing_frame_handler.py b/imap_processing/tests/spice/test_pointing_frame_handler.py index bf13705be..96b6881af 100644 --- a/imap_processing/tests/spice/test_pointing_frame_handler.py +++ b/imap_processing/tests/spice/test_pointing_frame_handler.py @@ -71,7 +71,6 @@ def et_times(ck_kernel, kernels): return et_times -# @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_get_et_times(kernels, ck_kernel): """Tests get_et_times function.""" @@ -83,7 +82,6 @@ def test_get_et_times(kernels, ck_kernel): assert len(et_times) == 57600 -# @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_average_quaternions(et_times, kernels): """Tests average_quaternions function.""" @@ -95,7 +93,6 @@ def test_average_quaternions(et_times, kernels): np.testing.assert_allclose(q_avg, q_avg_expected, atol=1e-1) -# @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_create_rotation_matrix(et_times, kernels): """Tests create_rotation_matrix function.""" @@ -113,7 +110,6 @@ def test_create_rotation_matrix(et_times, kernels): np.testing.assert_allclose(rotation_matrix, rotation_matrix_expected, atol=1e-4) -# @pytest.mark.xfail(reason="Will fail unless kernels in pointing_frame/test_data.") def test_create_pointing_frame(monkeypatch, kernel_path, ck_kernel): """Tests create_pointing_frame function.""" monkeypatch.setenv("EFS_MOUNT_PATH", str(kernel_path)) From fd7971c1ededfb68fdbc75d07fa71d0c18582be2 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Wed, 21 Aug 2024 10:59:54 -0600 Subject: [PATCH 17/32] response to pr --- .../spice/test_pointing_frame_handler.py | 46 -- poetry.lock | 454 +----------------- pyproject.toml | 2 - 3 files changed, 2 insertions(+), 500 deletions(-) diff --git a/imap_processing/tests/spice/test_pointing_frame_handler.py b/imap_processing/tests/spice/test_pointing_frame_handler.py index 96b6881af..d83442cbc 100644 --- a/imap_processing/tests/spice/test_pointing_frame_handler.py +++ b/imap_processing/tests/spice/test_pointing_frame_handler.py @@ -4,7 +4,6 @@ import sys from pathlib import Path -import matplotlib.pyplot as plt import numpy as np import pytest import spiceypy as spice @@ -135,48 +134,3 @@ def test_create_pointing_frame(monkeypatch, kernel_path, ck_kernel): # Verify imap_dps.bc has been created. assert (kernel_path / "imap_dps.bc").exists() - - -def declination_plot(kernels, et_times): - """Tests Inertial z axis and provides visualization.""" - - z_eclip_time = [] - - with spice.KernelPool(kernels): - # Converts rectangular coordinates to spherical coordinates. - - for tdb in et_times: - # Rotation matrix from IMAP spacecraft frame to ECLIPJ2000. - body_rots = spice.pxform("IMAP_SPACECRAFT", "ECLIPJ2000", tdb) - # z-axis of the ECLIPJ2000 frame. - z_eclip_time.append(body_rots[:, 2]) - - q_avg = average_quaternions(et_times) - z_avg = spice.q2m(list(q_avg))[:, 2] - - # Create visualization - declination_list = [] - for time in z_eclip_time: - _, _, declination = spice.recrad(list(time)) - declination_list.append(declination) - - # Average declination. - _, _, avg_declination = spice.recrad(list(z_avg)) - - # Plotting for visualization - plt.figure() - plt.plot( - et_times, np.array(declination_list) * 180 / np.pi, "-b", label="Declination" - ) - plt.plot( - et_times, - np.full(len(et_times), avg_declination * 180 / np.pi), - "-r", - linewidth=2, - label="mean declination for pointing frame", - ) - plt.xlabel("Ephemeris Time") - plt.ylabel("Spacecraft Spin Axis Declination") - plt.ticklabel_format(useOffset=False) - plt.legend() - plt.show() diff --git a/poetry.lock b/poetry.lock index 38e475799..ff98390a2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "accessible-pygments" @@ -378,69 +378,6 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -[[package]] -name = "contourpy" -version = "1.2.1" -description = "Python library for calculating contours of 2D quadrilateral grids" -optional = true -python-versions = ">=3.9" -files = [ - {file = "contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040"}, - {file = "contourpy-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b"}, - {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd"}, - {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619"}, - {file = "contourpy-1.2.1-cp310-cp310-win32.whl", hash = "sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8"}, - {file = "contourpy-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9"}, - {file = "contourpy-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5"}, - {file = "contourpy-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df"}, - {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205"}, - {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8"}, - {file = "contourpy-1.2.1-cp311-cp311-win32.whl", hash = "sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec"}, - {file = "contourpy-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922"}, - {file = "contourpy-1.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc"}, - {file = "contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b"}, - {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce"}, - {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4"}, - {file = "contourpy-1.2.1-cp312-cp312-win32.whl", hash = "sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f"}, - {file = "contourpy-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce"}, - {file = "contourpy-1.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b"}, - {file = "contourpy-1.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445"}, - {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02"}, - {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083"}, - {file = "contourpy-1.2.1-cp39-cp39-win32.whl", hash = "sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba"}, - {file = "contourpy-1.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f"}, - {file = "contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c"}, -] - -[package.dependencies] -numpy = ">=1.20" - -[package.extras] -bokeh = ["bokeh", "selenium"] -docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.8.0)", "types-Pillow"] -test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] - [[package]] name = "coverage" version = "7.6.1" @@ -528,21 +465,6 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] -[[package]] -name = "cycler" -version = "0.12.1" -description = "Composable style cycles" -optional = true -python-versions = ">=3.8" -files = [ - {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, - {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, -] - -[package.extras] -docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] -tests = ["pytest", "pytest-cov", "pytest-xdist"] - [[package]] name = "deepmerge" version = "1.1.1" @@ -617,71 +539,6 @@ docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1 testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] typing = ["typing-extensions (>=4.8)"] -[[package]] -name = "fonttools" -version = "4.53.1" -description = "Tools to manipulate font files" -optional = true -python-versions = ">=3.8" -files = [ - {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, - {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, - {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, - {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, - {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, - {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, - {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, - {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, - {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, - {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, - {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, - {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, - {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, - {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, - {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, - {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, - {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, - {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, - {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, - {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, - {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, - {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, - {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, - {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, - {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, - {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, - {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, - {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, - {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, - {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, - {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, - {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, - {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, - {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, - {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, - {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, - {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, - {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, - {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, - {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, - {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, - {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, -] - -[package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] -graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres", "pycairo", "scipy"] -lxml = ["lxml (>=4.0)"] -pathops = ["skia-pathops (>=0.5.0)"] -plot = ["matplotlib"] -repacker = ["uharfbuzz (>=0.23.0)"] -symfont = ["sympy"] -type1 = ["xattr"] -ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.1.0)"] -woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] - [[package]] name = "identify" version = "2.6.0" @@ -751,24 +608,6 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke perf = ["ipython"] test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] -[[package]] -name = "importlib-resources" -version = "6.4.3" -description = "Read resources from Python packages" -optional = true -python-versions = ">=3.8" -files = [ - {file = "importlib_resources-6.4.3-py3-none-any.whl", hash = "sha256:2d6dfe3b9e055f72495c2085890837fc8c758984e209115c8792bddcb762cd93"}, - {file = "importlib_resources-6.4.3.tar.gz", hash = "sha256:4a202b9b9d38563b46da59221d77bb73862ab5d79d461307bcb826d725448b98"}, -] - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} - -[package.extras] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] - [[package]] name = "iniconfig" version = "2.0.0" @@ -832,119 +671,6 @@ files = [ [package.dependencies] referencing = ">=0.31.0" -[[package]] -name = "kiwisolver" -version = "1.4.5" -description = "A fast implementation of the Cassowary constraint solver" -optional = true -python-versions = ">=3.7" -files = [ - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, - {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, - {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, - {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, - {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, - {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, - {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, - {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, - {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, - {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, - {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, - {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, -] - [[package]] name = "markupsafe" version = "2.1.5" @@ -1014,70 +740,6 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] -[[package]] -name = "matplotlib" -version = "3.9.2" -description = "Python plotting package" -optional = true -python-versions = ">=3.9" -files = [ - {file = "matplotlib-3.9.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9d78bbc0cbc891ad55b4f39a48c22182e9bdaea7fc0e5dbd364f49f729ca1bbb"}, - {file = "matplotlib-3.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c375cc72229614632c87355366bdf2570c2dac01ac66b8ad048d2dabadf2d0d4"}, - {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d94ff717eb2bd0b58fe66380bd8b14ac35f48a98e7c6765117fe67fb7684e64"}, - {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab68d50c06938ef28681073327795c5db99bb4666214d2d5f880ed11aeaded66"}, - {file = "matplotlib-3.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:65aacf95b62272d568044531e41de26285d54aec8cb859031f511f84bd8b495a"}, - {file = "matplotlib-3.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:3fd595f34aa8a55b7fc8bf9ebea8aa665a84c82d275190a61118d33fbc82ccae"}, - {file = "matplotlib-3.9.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d8dd059447824eec055e829258ab092b56bb0579fc3164fa09c64f3acd478772"}, - {file = "matplotlib-3.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c797dac8bb9c7a3fd3382b16fe8f215b4cf0f22adccea36f1545a6d7be310b41"}, - {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d719465db13267bcef19ea8954a971db03b9f48b4647e3860e4bc8e6ed86610f"}, - {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8912ef7c2362f7193b5819d17dae8629b34a95c58603d781329712ada83f9447"}, - {file = "matplotlib-3.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7741f26a58a240f43bee74965c4882b6c93df3e7eb3de160126d8c8f53a6ae6e"}, - {file = "matplotlib-3.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:ae82a14dab96fbfad7965403c643cafe6515e386de723e498cf3eeb1e0b70cc7"}, - {file = "matplotlib-3.9.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ac43031375a65c3196bee99f6001e7fa5bdfb00ddf43379d3c0609bdca042df9"}, - {file = "matplotlib-3.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be0fc24a5e4531ae4d8e858a1a548c1fe33b176bb13eff7f9d0d38ce5112a27d"}, - {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf81de2926c2db243c9b2cbc3917619a0fc85796c6ba4e58f541df814bbf83c7"}, - {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ee45bc4245533111ced13f1f2cace1e7f89d1c793390392a80c139d6cf0e6c"}, - {file = "matplotlib-3.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:306c8dfc73239f0e72ac50e5a9cf19cc4e8e331dd0c54f5e69ca8758550f1e1e"}, - {file = "matplotlib-3.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:5413401594cfaff0052f9d8b1aafc6d305b4bd7c4331dccd18f561ff7e1d3bd3"}, - {file = "matplotlib-3.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:18128cc08f0d3cfff10b76baa2f296fc28c4607368a8402de61bb3f2eb33c7d9"}, - {file = "matplotlib-3.9.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4876d7d40219e8ae8bb70f9263bcbe5714415acfdf781086601211335e24f8aa"}, - {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d9f07a80deab4bb0b82858a9e9ad53d1382fd122be8cde11080f4e7dfedb38b"}, - {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7c0410f181a531ec4e93bbc27692f2c71a15c2da16766f5ba9761e7ae518413"}, - {file = "matplotlib-3.9.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:909645cce2dc28b735674ce0931a4ac94e12f5b13f6bb0b5a5e65e7cea2c192b"}, - {file = "matplotlib-3.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:f32c7410c7f246838a77d6d1eff0c0f87f3cb0e7c4247aebea71a6d5a68cab49"}, - {file = "matplotlib-3.9.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:37e51dd1c2db16ede9cfd7b5cabdfc818b2c6397c83f8b10e0e797501c963a03"}, - {file = "matplotlib-3.9.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b82c5045cebcecd8496a4d694d43f9cc84aeeb49fe2133e036b207abe73f4d30"}, - {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f053c40f94bc51bc03832a41b4f153d83f2062d88c72b5e79997072594e97e51"}, - {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbe196377a8248972f5cede786d4c5508ed5f5ca4a1e09b44bda889958b33f8c"}, - {file = "matplotlib-3.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5816b1e1fe8c192cbc013f8f3e3368ac56fbecf02fb41b8f8559303f24c5015e"}, - {file = "matplotlib-3.9.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:cef2a73d06601437be399908cf13aee74e86932a5ccc6ccdf173408ebc5f6bb2"}, - {file = "matplotlib-3.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e0830e188029c14e891fadd99702fd90d317df294c3298aad682739c5533721a"}, - {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ba9c1299c920964e8d3857ba27173b4dbb51ca4bab47ffc2c2ba0eb5e2cbc5"}, - {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cd93b91ab47a3616b4d3c42b52f8363b88ca021e340804c6ab2536344fad9ca"}, - {file = "matplotlib-3.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6d1ce5ed2aefcdce11904fc5bbea7d9c21fff3d5f543841edf3dea84451a09ea"}, - {file = "matplotlib-3.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:b2696efdc08648536efd4e1601b5fd491fd47f4db97a5fbfd175549a7365c1b2"}, - {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d52a3b618cb1cbb769ce2ee1dcdb333c3ab6e823944e9a2d36e37253815f9556"}, - {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:039082812cacd6c6bec8e17a9c1e6baca230d4116d522e81e1f63a74d01d2e21"}, - {file = "matplotlib-3.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6758baae2ed64f2331d4fd19be38b7b4eae3ecec210049a26b6a4f3ae1c85dcc"}, - {file = "matplotlib-3.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:050598c2b29e0b9832cde72bcf97627bf00262adbc4a54e2b856426bb2ef0697"}, - {file = "matplotlib-3.9.2.tar.gz", hash = "sha256:96ab43906269ca64a6366934106fa01534454a69e471b7bf3d79083981aaab92"}, -] - -[package.dependencies] -contourpy = ">=1.0.1" -cycler = ">=0.10" -fonttools = ">=4.22.0" -importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} -kiwisolver = ">=1.3.1" -numpy = ">=1.23" -packaging = ">=20.0" -pillow = ">=8" -pyparsing = ">=2.3.1" -python-dateutil = ">=2.7" - -[package.extras] -dev = ["meson-python (>=0.13.1)", "numpy (>=1.25)", "pybind11 (>=2.6)", "setuptools (>=64)", "setuptools_scm (>=7)"] - [[package]] name = "mistune" version = "3.0.2" @@ -1342,103 +1004,6 @@ files = [ {file = "picobox-4.0.0.tar.gz", hash = "sha256:114da1b5606b2f615e8b0eb68d04198ad9de75af5adbcf5b36fe4f664ab927b6"}, ] -[[package]] -name = "pillow" -version = "10.4.0" -description = "Python Imaging Library (Fork)" -optional = true -python-versions = ">=3.8" -files = [ - {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, - {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, - {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, - {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, - {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, - {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, - {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, - {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, - {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, - {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, - {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, - {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, - {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, - {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, - {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, - {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, - {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, - {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, - {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, - {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] -fpx = ["olefile"] -mic = ["olefile"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] -typing = ["typing-extensions"] -xmp = ["defusedxml"] - [[package]] name = "platformdirs" version = "4.2.2" @@ -1530,20 +1095,6 @@ files = [ [package.extras] windows-terminal = ["colorama (>=0.4.6)"] -[[package]] -name = "pyparsing" -version = "3.1.2" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -optional = true -python-versions = ">=3.6.8" -files = [ - {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, - {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - [[package]] name = "pytest" version = "8.3.2" @@ -2225,11 +1776,10 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [extras] dev = ["mypy", "pre-commit", "ruff"] doc = ["numpydoc", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-openapi"] -plotting = ["matplotlib"] test = ["openpyxl", "pytest", "pytest-cov"] tools = ["openpyxl", "pandas"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<4" -content-hash = "f56e3289477dc3ecc3c98e94297e8a88fcf973d2c0aacbe7890238fed878500c" +content-hash = "f750033025b765826c827adb1142fd59444e13a985755c2a6efc3a207348a959" diff --git a/pyproject.toml b/pyproject.toml index c9d6528e0..598c512e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,14 +52,12 @@ ruff = {version="==0.2.1", optional=true} sphinx = {version="*", optional=true} sphinxcontrib-openapi = {version="^0.8.3", optional=true} mypy = {version="^1.10.1", optional=true} -matplotlib = {version="^3.7.1", optional=true} [tool.poetry.extras] dev = ["pre-commit", "ruff", "mypy"] doc = ["numpydoc", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-openapi"] test = ["openpyxl", "pytest", "pytest-cov"] tools= ["openpyxl", "pandas"] -plotting = ["matplotlib"] [project.urls] homepage = "https://github.com/IMAP-Science-Operations-Center" From b2e8bf05e3c3279ad3f239553a130849a832bab7 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Wed, 21 Aug 2024 12:30:10 -0600 Subject: [PATCH 18/32] added new path --- .../spice/pointing_frame_handler.py | 9 ++-- .../spice/test_pointing_frame_handler.py | 48 ++++--------------- 2 files changed, 13 insertions(+), 44 deletions(-) diff --git a/imap_processing/spice/pointing_frame_handler.py b/imap_processing/spice/pointing_frame_handler.py index 0f3f86776..7bab38667 100644 --- a/imap_processing/spice/pointing_frame_handler.py +++ b/imap_processing/spice/pointing_frame_handler.py @@ -32,7 +32,7 @@ def get_et_times(ck_kernel: str) -> tuple[float, float, np.ndarray]: """ - Create the pointing frame. + Get timerange for pointing start and stop. Parameters ---------- @@ -42,9 +42,9 @@ def get_et_times(ck_kernel: str) -> tuple[float, float, np.ndarray]: Returns ------- et_start : float - Start time of ck_kernel. + Pointing start time. et_end : float - End time of ck_kernel. + Pointing end time. et_times : numpy.ndarray Array of times between et_start and et_end. """ @@ -80,7 +80,6 @@ def average_quaternions(et_times: np.ndarray) -> NDArray: q_avg : np.ndarray Average quaternion. """ - z_eclip_time = [] aggregate = np.zeros((4, 4)) for tdb in et_times: @@ -97,8 +96,6 @@ def average_quaternions(et_times: np.ndarray) -> NDArray: # Convert rotation matrix to quaternion. # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.m2q body_quat = spice.m2q(body_rots) - # z-axis of the ECLIPJ2000 frame. - z_eclip_time.append(body_rots[:, 2]) # Standardize the quaternion so that they may be compared. body_quat = body_quat * np.sign(body_quat[0]) diff --git a/imap_processing/tests/spice/test_pointing_frame_handler.py b/imap_processing/tests/spice/test_pointing_frame_handler.py index d83442cbc..297ab2937 100644 --- a/imap_processing/tests/spice/test_pointing_frame_handler.py +++ b/imap_processing/tests/spice/test_pointing_frame_handler.py @@ -1,9 +1,5 @@ """Tests Pointing Frame Generation.""" -import shutil -import sys -from pathlib import Path - import numpy as np import pytest import spiceypy as spice @@ -17,44 +13,20 @@ @pytest.fixture() -def kernel_path(tmp_path): - """Create path to kernels.""" - - test_dir = ( - Path(sys.modules[__name__.split(".")[0]].__file__).parent - / "tests" - / "spice" - / "test_data" - ) - - kernels = [ - "naif0012.tls", - "imap_science_0001.tf", - "imap_sclk_0000.tsc", - "imap_wkcp.tf", - "imap_spin.bc", - ] - - for file in test_dir.iterdir(): - if file.name in kernels: - shutil.copy(file, tmp_path / file.name) - - return tmp_path - - -@pytest.fixture() -def kernels(kernel_path): +def kernels(spice_test_data_path): """Create kernel list.""" - kernels = [str(file) for file in kernel_path.iterdir()] + kernels = [str(file) for file in spice_test_data_path.iterdir()] return kernels @pytest.fixture() -def ck_kernel(kernel_path): +def ck_kernel(spice_test_data_path): """Create ck kernel.""" ck_kernel = [ - str(file) for file in kernel_path.iterdir() if file.name == "imap_spin.bc" + str(file) + for file in spice_test_data_path.iterdir() + if file.name == "imap_spin.bc" ] return ck_kernel @@ -109,13 +81,13 @@ def test_create_rotation_matrix(et_times, kernels): np.testing.assert_allclose(rotation_matrix, rotation_matrix_expected, atol=1e-4) -def test_create_pointing_frame(monkeypatch, kernel_path, ck_kernel): +def test_create_pointing_frame(monkeypatch, spice_test_data_path, ck_kernel, tmp_path): """Tests create_pointing_frame function.""" - monkeypatch.setenv("EFS_MOUNT_PATH", str(kernel_path)) + monkeypatch.setenv("EFS_MOUNT_PATH", str(spice_test_data_path)) create_pointing_frame() # After imap_dps.bc has been created. - kernels = [str(file) for file in kernel_path.iterdir()] + kernels = [str(file) for file in spice_test_data_path.iterdir()] with spice.KernelPool(kernels): et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) @@ -133,4 +105,4 @@ def test_create_pointing_frame(monkeypatch, kernel_path, ck_kernel): np.testing.assert_allclose(rotation_matrix_1, rotation_matrix_expected, atol=1e-4) # Verify imap_dps.bc has been created. - assert (kernel_path / "imap_dps.bc").exists() + assert (spice_test_data_path / "imap_dps.bc").exists() From 682c5e934ba467392dff31bcfa3a0e160f6b6c26 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Wed, 21 Aug 2024 12:40:53 -0600 Subject: [PATCH 19/32] pr resposne --- .../tests/spice/test_pointing_frame_handler.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/imap_processing/tests/spice/test_pointing_frame_handler.py b/imap_processing/tests/spice/test_pointing_frame_handler.py index 297ab2937..c8ec13eef 100644 --- a/imap_processing/tests/spice/test_pointing_frame_handler.py +++ b/imap_processing/tests/spice/test_pointing_frame_handler.py @@ -22,14 +22,8 @@ def kernels(spice_test_data_path): @pytest.fixture() def ck_kernel(spice_test_data_path): - """Create ck kernel.""" - ck_kernel = [ - str(file) - for file in spice_test_data_path.iterdir() - if file.name == "imap_spin.bc" - ] - - return ck_kernel + """Location of ck kernel to create pointing kernel from.""" + return spice_test_data_path / "imap_spin.bc" @pytest.fixture() @@ -37,7 +31,7 @@ def et_times(ck_kernel, kernels): """Tests get_et_times function.""" with spice.KernelPool(kernels): - et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) + et_start, et_end, et_times = get_et_times(str(ck_kernel)) return et_times @@ -46,7 +40,7 @@ def test_get_et_times(kernels, ck_kernel): """Tests get_et_times function.""" with spice.KernelPool(kernels): - et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) + et_start, et_end, et_times = get_et_times(str(ck_kernel)) assert et_start == 802008069.184905 assert et_end == 802015267.184906 @@ -90,7 +84,7 @@ def test_create_pointing_frame(monkeypatch, spice_test_data_path, ck_kernel, tmp kernels = [str(file) for file in spice_test_data_path.iterdir()] with spice.KernelPool(kernels): - et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) + et_start, et_end, et_times = get_et_times(str(ck_kernel)) rotation_matrix_1 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 100) rotation_matrix_2 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 1000) From 3353f072c4a5b87e630bc0f7856e93c17b8decd6 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Thu, 22 Aug 2024 12:30:49 -0600 Subject: [PATCH 20/32] response to pr --- imap_processing/spice/pointing_frame_handler.py | 10 ++++------ .../tests/spice/test_pointing_frame_handler.py | 10 +++++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/imap_processing/spice/pointing_frame_handler.py b/imap_processing/spice/pointing_frame_handler.py index 7bab38667..02f44492f 100644 --- a/imap_processing/spice/pointing_frame_handler.py +++ b/imap_processing/spice/pointing_frame_handler.py @@ -32,7 +32,7 @@ def get_et_times(ck_kernel: str) -> tuple[float, float, np.ndarray]: """ - Get timerange for pointing start and stop. + Get times for pointing start and stop. Parameters ---------- @@ -59,9 +59,9 @@ def get_et_times(ck_kernel: str) -> tuple[float, float, np.ndarray]: cover = spice.ckcov(ck_kernel, int(id_imap_spacecraft), True, "SEGMENT", 0, "TDB") # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.wnfetd et_start, et_end = spice.wnfetd(cover, 0) - # Assumes a pointing is ~ 1 day. - # 1 spin/15 seconds * 86400 seconds/pointing * 10 quaternions / spin - et_times = np.linspace(et_start, et_end, 57600) + # 1 spin/15 seconds; 10 quaternions / spin + num_samples = (et_end - et_start) / 15 * 10 + et_times = np.linspace(et_start, et_end, int(num_samples)) return et_start, et_end, et_times @@ -81,7 +81,6 @@ def average_quaternions(et_times: np.ndarray) -> NDArray: Average quaternion. """ aggregate = np.zeros((4, 4)) - for tdb in et_times: # we use a quick and dirty method here for grabbing the quaternions # from the attitude kernel. Depending on how well the kernel input @@ -99,7 +98,6 @@ def average_quaternions(et_times: np.ndarray) -> NDArray: # Standardize the quaternion so that they may be compared. body_quat = body_quat * np.sign(body_quat[0]) - # Aggregate quaternions into a single matrix. aggregate += np.outer(body_quat, body_quat) diff --git a/imap_processing/tests/spice/test_pointing_frame_handler.py b/imap_processing/tests/spice/test_pointing_frame_handler.py index c8ec13eef..8972d061f 100644 --- a/imap_processing/tests/spice/test_pointing_frame_handler.py +++ b/imap_processing/tests/spice/test_pointing_frame_handler.py @@ -1,5 +1,7 @@ """Tests Pointing Frame Generation.""" +import os + import numpy as np import pytest import spiceypy as spice @@ -44,7 +46,8 @@ def test_get_et_times(kernels, ck_kernel): assert et_start == 802008069.184905 assert et_end == 802015267.184906 - assert len(et_times) == 57600 + assert et_times[0] == et_start + assert et_times[-1] == et_end def test_average_quaternions(et_times, kernels): @@ -54,8 +57,8 @@ def test_average_quaternions(et_times, kernels): q_avg = average_quaternions(et_times) # Generated from MATLAB code results - q_avg_expected = np.array([-0.6838, 0.5480, -0.4469, -0.1802]) - np.testing.assert_allclose(q_avg, q_avg_expected, atol=1e-1) + q_avg_expected = np.array([-0.6611, 0.4981, -0.5019, -0.2509]) + np.testing.assert_allclose(q_avg, q_avg_expected, atol=1e-4) def test_create_rotation_matrix(et_times, kernels): @@ -100,3 +103,4 @@ def test_create_pointing_frame(monkeypatch, spice_test_data_path, ck_kernel, tmp # Verify imap_dps.bc has been created. assert (spice_test_data_path / "imap_dps.bc").exists() + os.remove(spice_test_data_path / "imap_dps.bc") From 64b0a4c1836af82203483a4dec5896224d2aa1de Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Thu, 22 Aug 2024 12:57:29 -0600 Subject: [PATCH 21/32] move to kernels.py --- imap_processing/spice/kernels.py | 214 ++++++++++++++++++++ imap_processing/tests/spice/test_kernels.py | 101 +++++++++ 2 files changed, 315 insertions(+) diff --git a/imap_processing/spice/kernels.py b/imap_processing/spice/kernels.py index 2d4e21154..aca6cce21 100644 --- a/imap_processing/spice/kernels.py +++ b/imap_processing/spice/kernels.py @@ -3,9 +3,12 @@ import functools import logging import os +from pathlib import Path from typing import Any, Callable, Optional +import numpy as np import spiceypy as spice +from numpy.typing import NDArray from spiceypy.utils.exceptions import SpiceyError logger = logging.getLogger(__name__) @@ -156,3 +159,214 @@ def wrapper_ensure_spice(*args: Any, **kwargs: Any) -> Any: return _decorator(f_py) else: return _decorator + + +@ensure_spice +def create_pointing_frame() -> Path: + """ + Create the pointing frame. + + Returns + ------- + path_to_pointing_frame : Path + Path to dps frame. + """ + # TODO: this part will change with ensure_spice decorator. + # Mount path to EFS. + mount_path = Path(os.getenv("EFS_MOUNT_PATH", "")) + + # TODO: this part will change with ensure_spice decorator. + kernels = [str(file) for file in mount_path.iterdir()] + ck_kernel = [str(file) for file in mount_path.iterdir() if file.suffix == ".bc"] + + # Furnish the kernels. + with spice.KernelPool(kernels): + # Get timerange for the pointing frame kernel. + et_start, et_end, et_times = _get_et_times(str(ck_kernel[0])) + # Create a rotation matrix + rotation_matrix = _create_rotation_matrix(et_times) + + # Convert the rotation matrix to a quaternion. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.m2q + q_avg = spice.m2q(rotation_matrix) + + # TODO: come up with naming convention. + path_to_pointing_frame = mount_path / "imap_dps.bc" + + # Open a new CK file, returning the handle of the opened file. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckopn + handle = spice.ckopn(str(path_to_pointing_frame), "CK", 0) + # Get the SCLK ID. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool + id_imap_sclk = spice.gipool("CK_-43000_SCLK", 0, 1) + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.sce2c + # Convert start and end times to SCLK. + sclk_begtim = spice.sce2c(int(id_imap_sclk), et_start) + sclk_endtim = spice.sce2c(int(id_imap_sclk), et_end) + + # Get the pointing frame ID. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool + id_imap_dps = spice.gipool("FRAME_IMAP_DPS", 0, 1) + + # Create the pointing frame kernel. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckw02 + spice.ckw02( + # Handle of an open CK file. + handle, + # Start time of the segment. + sclk_begtim, + # End time of the segment. + sclk_endtim, + # Pointing frame ID. + int(id_imap_dps), + # Reference frame. + "ECLIPJ2000", # Reference frame + # Identifier. + "IMAP_DPS", + # Number of pointing intervals. + 1, + # Start times of individual pointing records within segment. + # Since there is only a single record this is equal to sclk_begtim. + np.array([sclk_begtim]), + # End times of individual pointing records within segment. + # Since there is only a single record this is equal to sclk_endtim. + np.array([sclk_endtim]), # Single stop time + # Average quaternion. + q_avg, + # 0.0 Angular rotation terms. + np.array([0.0, 0.0, 0.0]), + # Rates (seconds per tick) at which the quaternion and + # angular velocity change. + np.array([1.0]), + ) + + # Close CK file. + spice.ckcls(handle) + + return path_to_pointing_frame + + +@ensure_spice +def _get_et_times(ck_kernel: str) -> tuple[float, float, np.ndarray]: + """ + Get times for pointing start and stop. + + Parameters + ---------- + ck_kernel : str + Path of ck_kernel used to create the pointing frame. + + Returns + ------- + et_start : float + Pointing start time. + et_end : float + Pointing end time. + et_times : numpy.ndarray + Array of times between et_start and et_end. + """ + # Get the spacecraft ID. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool + id_imap_spacecraft = spice.gipool("FRAME_IMAP_SPACECRAFT", 0, 1) + + # TODO: Queried pointing start and stop times here. + + # Get the coverage window + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckcov + cover = spice.ckcov(ck_kernel, int(id_imap_spacecraft), True, "SEGMENT", 0, "TDB") + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.wnfetd + et_start, et_end = spice.wnfetd(cover, 0) + # 1 spin/15 seconds; 10 quaternions / spin + num_samples = (et_end - et_start) / 15 * 10 + et_times = np.linspace(et_start, et_end, int(num_samples)) + + return et_start, et_end, et_times + + +@ensure_spice +def _average_quaternions(et_times: np.ndarray) -> NDArray: + """ + Average the quaternions. + + Parameters + ---------- + et_times : numpy.ndarray + Array of times between et_start and et_end. + + Returns + ------- + q_avg : np.ndarray + Average quaternion. + """ + aggregate = np.zeros((4, 4)) + for tdb in et_times: + # we use a quick and dirty method here for grabbing the quaternions + # from the attitude kernel. Depending on how well the kernel input + # data is built and sampled, there may or may not be aliasing with this + # approach. If it turns out that we need to pull the quaternions + # directly from the CK there are several routines that exist to do this + # but it's not straight forward. We'll revisit this if needed. + + # Rotation matrix from IMAP spacecraft frame to ECLIPJ2000. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.pxform + body_rots = spice.pxform("IMAP_SPACECRAFT", "ECLIPJ2000", tdb) + # Convert rotation matrix to quaternion. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.m2q + body_quat = spice.m2q(body_rots) + + # Standardize the quaternion so that they may be compared. + body_quat = body_quat * np.sign(body_quat[0]) + # Aggregate quaternions into a single matrix. + aggregate += np.outer(body_quat, body_quat) + + # Reference: "On Averaging Rotations" + # Link: https://link.springer.com/content/pdf/10.1023/A:1011129215388.pdf + aggregate /= len(et_times) + + # Compute eigen values and vectors of the matrix A + # Eigenvalues tell you how much "influence" each + # direction (eigenvector) has. + # The largest eigenvalue corresponds to the direction + # that has the most influence. + # The eigenvector corresponding to the largest + # eigenvalue points in the direction that has the most + # combined rotation influence. + eigvals, eigvecs = np.linalg.eig(aggregate) + # q0: The scalar part of the quaternion. + # q1, q2, q3: The vector part of the quaternion. + q_avg = eigvecs[:, np.argmax(eigvals)] + + return q_avg + + +@ensure_spice +def _create_rotation_matrix(et_times: np.ndarray) -> NDArray: + """ + Create a rotation matrix. + + Parameters + ---------- + et_times : numpy.ndarray + Array of times between et_start and et_end. + + Returns + ------- + rotation_matrix : np.ndarray + Rotation matrix. + """ + # Averaged quaternions. + q_avg = _average_quaternions(et_times) + + # Converts the averaged quaternion (q_avg) into a rotation matrix + # and get inertial z axis. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.q2m + z_avg = spice.q2m(list(q_avg))[:, 2] + # y_avg is perpendicular to both z_avg and the standard Z-axis. + y_avg = np.cross(z_avg, [0, 0, 1]) + # x_avg is perpendicular to y_avg and z_avg. + x_avg = np.cross(y_avg, z_avg) + + # Construct the rotation matrix from x_avg, y_avg, z_avg + rotation_matrix = np.asarray([x_avg, y_avg, z_avg]) + + return rotation_matrix diff --git a/imap_processing/tests/spice/test_kernels.py b/imap_processing/tests/spice/test_kernels.py index c8ce926ad..29b6ec675 100644 --- a/imap_processing/tests/spice/test_kernels.py +++ b/imap_processing/tests/spice/test_kernels.py @@ -1,10 +1,19 @@ """Tests coverage for imap_processing/spice/kernels.py""" +import os + +import numpy as np import pytest import spiceypy as spice from spiceypy.utils.exceptions import SpiceyError from imap_processing.spice import kernels +from imap_processing.spice.kernels import ( + _average_quaternions, + _create_rotation_matrix, + _get_et_times, + create_pointing_frame, +) @kernels.ensure_spice @@ -67,3 +76,95 @@ def test_ensure_spice_key_error(): # functions that it decorates. with pytest.raises(SpiceyError): _ = wrapped(577365941.184, "ISOC", 3) == "2018-04-18T23:24:31.998" + + +@pytest.fixture() +def kernels(spice_test_data_path): + """Create kernel list.""" + kernels = [str(file) for file in spice_test_data_path.iterdir()] + + return kernels + + +@pytest.fixture() +def ck_kernel(spice_test_data_path): + """Location of ck kernel to create pointing kernel from.""" + return spice_test_data_path / "imap_spin.bc" + + +@pytest.fixture() +def et_times(ck_kernel, kernels): + """Tests get_et_times function.""" + + with spice.KernelPool(kernels): + et_start, et_end, et_times = _get_et_times(str(ck_kernel)) + + return et_times + + +def test_get_et_times(kernels, ck_kernel): + """Tests get_et_times function.""" + + with spice.KernelPool(kernels): + et_start, et_end, et_times = _get_et_times(str(ck_kernel)) + + assert et_start == 802008069.184905 + assert et_end == 802015267.184906 + assert et_times[0] == et_start + assert et_times[-1] == et_end + + +def test_average_quaternions(et_times, kernels): + """Tests average_quaternions function.""" + + with spice.KernelPool(kernels): + q_avg = _average_quaternions(et_times) + + # Generated from MATLAB code results + q_avg_expected = np.array([-0.6611, 0.4981, -0.5019, -0.2509]) + np.testing.assert_allclose(q_avg, q_avg_expected, atol=1e-4) + + +def test_create_rotation_matrix(et_times, kernels): + """Tests create_rotation_matrix function.""" + + with spice.KernelPool(kernels): + rotation_matrix = _create_rotation_matrix(et_times) + q_avg = _average_quaternions(et_times) + z_avg = spice.q2m(list(q_avg))[:, 2] + + rotation_matrix_expected = np.array( + [[0.0000, 0.0000, 1.0000], [0.9104, -0.4136, 0.0000], [0.4136, 0.9104, 0.0000]] + ) + z_avg_expected = np.array([0.4136, 0.9104, 0.0000]) + + np.testing.assert_allclose(z_avg, z_avg_expected, atol=1e-4) + np.testing.assert_allclose(rotation_matrix, rotation_matrix_expected, atol=1e-4) + + +def test_create_pointing_frame(monkeypatch, spice_test_data_path, ck_kernel, tmp_path): + """Tests create_pointing_frame function.""" + monkeypatch.setenv("EFS_MOUNT_PATH", str(spice_test_data_path)) + create_pointing_frame() + + # After imap_dps.bc has been created. + kernels = [str(file) for file in spice_test_data_path.iterdir()] + + with spice.KernelPool(kernels): + et_start, et_end, et_times = _get_et_times(str(ck_kernel)) + + rotation_matrix_1 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 100) + rotation_matrix_2 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 1000) + + # All the rotation matrices should be the same. + assert np.array_equal(rotation_matrix_1, rotation_matrix_2) + + # Nick Dutton's MATLAB code result + rotation_matrix_expected = np.array( + [[0.0000, 0.0000, 1.0000], [0.9104, -0.4136, 0.0000], [0.4136, 0.9104, 0.0000]] + ) + np.testing.assert_allclose(rotation_matrix_1, rotation_matrix_expected, atol=1e-4) + + # Verify imap_dps.bc has been created. + assert (spice_test_data_path / "imap_dps.bc").exists() + os.remove(spice_test_data_path / "imap_dps.bc") From f208bd894fc7c97c87854b81104561a2b5d3cc52 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Thu, 22 Aug 2024 13:45:47 -0600 Subject: [PATCH 22/32] tests work --- imap_processing/tests/spice/test_kernels.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/imap_processing/tests/spice/test_kernels.py b/imap_processing/tests/spice/test_kernels.py index 29b6ec675..9f72271b2 100644 --- a/imap_processing/tests/spice/test_kernels.py +++ b/imap_processing/tests/spice/test_kernels.py @@ -7,22 +7,22 @@ import spiceypy as spice from spiceypy.utils.exceptions import SpiceyError -from imap_processing.spice import kernels from imap_processing.spice.kernels import ( _average_quaternions, _create_rotation_matrix, _get_et_times, create_pointing_frame, + ensure_spice, ) -@kernels.ensure_spice +@ensure_spice def single_wrap_et2utc(et, fmt, prec): """Directly decorate a spice function with ensure_spice for use in tests""" return spice.et2utc(et, fmt, prec) -@kernels.ensure_spice +@ensure_spice def double_wrap_et2utc(et, fmt, prec): """Decorate a spice function twice with ensure_spice for use in tests. This simulates some decorated outer functions that call lower level functions @@ -30,13 +30,13 @@ def double_wrap_et2utc(et, fmt, prec): return single_wrap_et2utc(et, fmt, prec) -@kernels.ensure_spice(time_kernels_only=True) +@ensure_spice(time_kernels_only=True) def single_wrap_et2utc_tk_only(et, fmt, prec): """Directly wrap a spice function with optional time_kernels_only set True""" return spice.et2utc(et, fmt, prec) -@kernels.ensure_spice(time_kernels_only=True) +@ensure_spice(time_kernels_only=True) def double_wrap_et2utc_tk_only(et, fmt, prec): """Decorate a spice function twice with ensure_spice for use in tests. This simulates some decorated outer functions that call lower level functions @@ -60,7 +60,7 @@ def test_ensure_spice_emus_mk_path(func, use_test_metakernel): def test_ensure_spice_time_kernels(): """Test functionality of ensure spice with timekernels set""" - wrapped = kernels.ensure_spice(spice.et2utc, time_kernels_only=True) + wrapped = ensure_spice(spice.et2utc, time_kernels_only=True) # TODO: Update/remove this test when a decision has been made about # whether IMAP will use the time_kernels_only functionality and the # ensure_spice decorator has been update. @@ -70,7 +70,7 @@ def test_ensure_spice_time_kernels(): def test_ensure_spice_key_error(): """Test functionality of ensure spice when all branches fail""" - wrapped = kernels.ensure_spice(spice.et2utc) + wrapped = ensure_spice(spice.et2utc) # The ensure_spice decorator should raise a SpiceyError when all attempts to # furnish a set of kernels with sufficient coverage for the spiceypy # functions that it decorates. From 3d38e6f416901e74f6b9092ac415d75f221c56d6 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Thu, 22 Aug 2024 15:19:17 -0600 Subject: [PATCH 23/32] update test --- imap_processing/spice/kernels.py | 135 ++++++++++---------- imap_processing/tests/spice/test_kernels.py | 89 ++++++------- 2 files changed, 101 insertions(+), 123 deletions(-) diff --git a/imap_processing/spice/kernels.py b/imap_processing/spice/kernels.py index aca6cce21..5e906df9e 100644 --- a/imap_processing/spice/kernels.py +++ b/imap_processing/spice/kernels.py @@ -169,79 +169,72 @@ def create_pointing_frame() -> Path: Returns ------- path_to_pointing_frame : Path - Path to dps frame. + Path to pointing frame. """ - # TODO: this part will change with ensure_spice decorator. - # Mount path to EFS. - mount_path = Path(os.getenv("EFS_MOUNT_PATH", "")) - - # TODO: this part will change with ensure_spice decorator. - kernels = [str(file) for file in mount_path.iterdir()] - ck_kernel = [str(file) for file in mount_path.iterdir() if file.suffix == ".bc"] - - # Furnish the kernels. - with spice.KernelPool(kernels): - # Get timerange for the pointing frame kernel. - et_start, et_end, et_times = _get_et_times(str(ck_kernel[0])) - # Create a rotation matrix - rotation_matrix = _create_rotation_matrix(et_times) - - # Convert the rotation matrix to a quaternion. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.m2q - q_avg = spice.m2q(rotation_matrix) - - # TODO: come up with naming convention. - path_to_pointing_frame = mount_path / "imap_dps.bc" - - # Open a new CK file, returning the handle of the opened file. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckopn - handle = spice.ckopn(str(path_to_pointing_frame), "CK", 0) - # Get the SCLK ID. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool - id_imap_sclk = spice.gipool("CK_-43000_SCLK", 0, 1) - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.sce2c - # Convert start and end times to SCLK. - sclk_begtim = spice.sce2c(int(id_imap_sclk), et_start) - sclk_endtim = spice.sce2c(int(id_imap_sclk), et_end) - - # Get the pointing frame ID. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool - id_imap_dps = spice.gipool("FRAME_IMAP_DPS", 0, 1) - - # Create the pointing frame kernel. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckw02 - spice.ckw02( - # Handle of an open CK file. - handle, - # Start time of the segment. - sclk_begtim, - # End time of the segment. - sclk_endtim, - # Pointing frame ID. - int(id_imap_dps), - # Reference frame. - "ECLIPJ2000", # Reference frame - # Identifier. - "IMAP_DPS", - # Number of pointing intervals. - 1, - # Start times of individual pointing records within segment. - # Since there is only a single record this is equal to sclk_begtim. - np.array([sclk_begtim]), - # End times of individual pointing records within segment. - # Since there is only a single record this is equal to sclk_endtim. - np.array([sclk_endtim]), # Single stop time - # Average quaternion. - q_avg, - # 0.0 Angular rotation terms. - np.array([0.0, 0.0, 0.0]), - # Rates (seconds per tick) at which the quaternion and - # angular velocity change. - np.array([1.0]), - ) + ck_kernel, _, _, _ = spice.kdata(0, "ck") + directory = Path(ck_kernel).parent + + # Get timerange for the pointing frame kernel. + et_start, et_end, et_times = _get_et_times(ck_kernel) + # Create a rotation matrix + rotation_matrix = _create_rotation_matrix(et_times) + + # Convert the rotation matrix to a quaternion. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.m2q + q_avg = spice.m2q(rotation_matrix) - # Close CK file. - spice.ckcls(handle) + # TODO: come up with naming convention. + path_to_pointing_frame = directory / "imap_dps.bc" + + # Open a new CK file, returning the handle of the opened file. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckopn + handle = spice.ckopn(str(path_to_pointing_frame), "CK", 0) + # Get the SCLK ID. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool + id_imap_sclk = spice.gipool("CK_-43000_SCLK", 0, 1) + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.sce2c + # Convert start and end times to SCLK. + sclk_begtim = spice.sce2c(int(id_imap_sclk), et_start) + sclk_endtim = spice.sce2c(int(id_imap_sclk), et_end) + + # Get the pointing frame ID. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool + id_imap_dps = spice.gipool("FRAME_IMAP_DPS", 0, 1) + + # Create the pointing frame kernel. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckw02 + spice.ckw02( + # Handle of an open CK file. + handle, + # Start time of the segment. + sclk_begtim, + # End time of the segment. + sclk_endtim, + # Pointing frame ID. + int(id_imap_dps), + # Reference frame. + "ECLIPJ2000", # Reference frame + # Identifier. + "IMAP_DPS", + # Number of pointing intervals. + 1, + # Start times of individual pointing records within segment. + # Since there is only a single record this is equal to sclk_begtim. + np.array([sclk_begtim]), + # End times of individual pointing records within segment. + # Since there is only a single record this is equal to sclk_endtim. + np.array([sclk_endtim]), # Single stop time + # Average quaternion. + q_avg, + # 0.0 Angular rotation terms. + np.array([0.0, 0.0, 0.0]), + # Rates (seconds per tick) at which the quaternion and + # angular velocity change. + np.array([1.0]), + ) + + # Close CK file. + spice.ckcls(handle) return path_to_pointing_frame diff --git a/imap_processing/tests/spice/test_kernels.py b/imap_processing/tests/spice/test_kernels.py index 9f72271b2..63155f875 100644 --- a/imap_processing/tests/spice/test_kernels.py +++ b/imap_processing/tests/spice/test_kernels.py @@ -16,6 +16,29 @@ ) +@pytest.fixture() +def kernels(spice_test_data_path): + """Furnish SPICE kernels for the entire test module.""" + kernels = [str(file) for file in spice_test_data_path.iterdir()] + return kernels + + +@pytest.fixture() +def et_times(kernels): + """Tests get_et_times function.""" + spice.furnsh(kernels) + + file, _, _, _ = spice.kdata(0, "ck") + et_start, et_end, et_times = _get_et_times(file) + + assert et_start == 802008069.184905 + assert et_end == 802015267.184906 + assert et_times[0] == et_start + assert et_times[-1] == et_end + + return et_times + + @ensure_spice def single_wrap_et2utc(et, fmt, prec): """Directly decorate a spice function with ensure_spice for use in tests""" @@ -78,47 +101,10 @@ def test_ensure_spice_key_error(): _ = wrapped(577365941.184, "ISOC", 3) == "2018-04-18T23:24:31.998" -@pytest.fixture() -def kernels(spice_test_data_path): - """Create kernel list.""" - kernels = [str(file) for file in spice_test_data_path.iterdir()] - - return kernels - - -@pytest.fixture() -def ck_kernel(spice_test_data_path): - """Location of ck kernel to create pointing kernel from.""" - return spice_test_data_path / "imap_spin.bc" - - -@pytest.fixture() -def et_times(ck_kernel, kernels): - """Tests get_et_times function.""" - - with spice.KernelPool(kernels): - et_start, et_end, et_times = _get_et_times(str(ck_kernel)) - - return et_times - - -def test_get_et_times(kernels, ck_kernel): - """Tests get_et_times function.""" - - with spice.KernelPool(kernels): - et_start, et_end, et_times = _get_et_times(str(ck_kernel)) - - assert et_start == 802008069.184905 - assert et_end == 802015267.184906 - assert et_times[0] == et_start - assert et_times[-1] == et_end - - def test_average_quaternions(et_times, kernels): """Tests average_quaternions function.""" - - with spice.KernelPool(kernels): - q_avg = _average_quaternions(et_times) + spice.furnsh(kernels) + q_avg = _average_quaternions(et_times) # Generated from MATLAB code results q_avg_expected = np.array([-0.6611, 0.4981, -0.5019, -0.2509]) @@ -127,11 +113,10 @@ def test_average_quaternions(et_times, kernels): def test_create_rotation_matrix(et_times, kernels): """Tests create_rotation_matrix function.""" - - with spice.KernelPool(kernels): - rotation_matrix = _create_rotation_matrix(et_times) - q_avg = _average_quaternions(et_times) - z_avg = spice.q2m(list(q_avg))[:, 2] + spice.furnsh(kernels) + rotation_matrix = _create_rotation_matrix(et_times) + q_avg = _average_quaternions(et_times) + z_avg = spice.q2m(list(q_avg))[:, 2] rotation_matrix_expected = np.array( [[0.0000, 0.0000, 1.0000], [0.9104, -0.4136, 0.0000], [0.4136, 0.9104, 0.0000]] @@ -142,19 +127,19 @@ def test_create_rotation_matrix(et_times, kernels): np.testing.assert_allclose(rotation_matrix, rotation_matrix_expected, atol=1e-4) -def test_create_pointing_frame(monkeypatch, spice_test_data_path, ck_kernel, tmp_path): +def test_create_pointing_frame(spice_test_data_path, kernels): """Tests create_pointing_frame function.""" - monkeypatch.setenv("EFS_MOUNT_PATH", str(spice_test_data_path)) + spice.furnsh(kernels) + ck_kernel, _, _, _ = spice.kdata(0, "ck") + et_start, et_end, et_times = _get_et_times(ck_kernel) create_pointing_frame() # After imap_dps.bc has been created. - kernels = [str(file) for file in spice_test_data_path.iterdir()] - - with spice.KernelPool(kernels): - et_start, et_end, et_times = _get_et_times(str(ck_kernel)) + dps_kernel = str(spice_test_data_path / "imap_dps.bc") - rotation_matrix_1 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 100) - rotation_matrix_2 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 1000) + spice.furnsh(dps_kernel) + rotation_matrix_1 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 100) + rotation_matrix_2 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 1000) # All the rotation matrices should be the same. assert np.array_equal(rotation_matrix_1, rotation_matrix_2) From 579ea27460b9e519b025898c29ec264ad7ee850b Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Thu, 22 Aug 2024 15:20:29 -0600 Subject: [PATCH 24/32] deleted files --- .../spice/pointing_frame_handler.py | 237 ------------------ .../spice/test_pointing_frame_handler.py | 106 -------- 2 files changed, 343 deletions(-) delete mode 100644 imap_processing/spice/pointing_frame_handler.py delete mode 100644 imap_processing/tests/spice/test_pointing_frame_handler.py diff --git a/imap_processing/spice/pointing_frame_handler.py b/imap_processing/spice/pointing_frame_handler.py deleted file mode 100644 index 02f44492f..000000000 --- a/imap_processing/spice/pointing_frame_handler.py +++ /dev/null @@ -1,237 +0,0 @@ -""" -Generate Pointing Frame. - -Notes ------ -Kernels that are required to run this code: -1. imap_science_0001.tf - pointing frame kernel -2. imap_sclk_0000.tsc - spacecraft clock kernel -3. imap_wkcp.tf - spacecraft frame kernel -4. naif0012.tls - standard NAIF leapsecond kernel -5. imap_spin.bc - test attitude kernel generated by simulate_imap_attitude.m. -These need to be placed in tests/pointing_frame/test_data. - -References ----------- -https://spiceypy.readthedocs.io/en/main/documentation.html. -""" - -import logging -import os -from pathlib import Path - -import numpy as np -import spiceypy as spice -from numpy.typing import NDArray - -logger = logging.getLogger(__name__) -logger.setLevel(logging.INFO) - -# TODO : Add multiple pointings to the pointing frame. - - -def get_et_times(ck_kernel: str) -> tuple[float, float, np.ndarray]: - """ - Get times for pointing start and stop. - - Parameters - ---------- - ck_kernel : str - Path of ck_kernel used to create the pointing frame. - - Returns - ------- - et_start : float - Pointing start time. - et_end : float - Pointing end time. - et_times : numpy.ndarray - Array of times between et_start and et_end. - """ - # Get the spacecraft ID. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool - id_imap_spacecraft = spice.gipool("FRAME_IMAP_SPACECRAFT", 0, 1) - - # TODO: Queried pointing start and stop times here. - - # Get the coverage window - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckcov - cover = spice.ckcov(ck_kernel, int(id_imap_spacecraft), True, "SEGMENT", 0, "TDB") - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.wnfetd - et_start, et_end = spice.wnfetd(cover, 0) - # 1 spin/15 seconds; 10 quaternions / spin - num_samples = (et_end - et_start) / 15 * 10 - et_times = np.linspace(et_start, et_end, int(num_samples)) - - return et_start, et_end, et_times - - -def average_quaternions(et_times: np.ndarray) -> NDArray: - """ - Average the quaternions. - - Parameters - ---------- - et_times : numpy.ndarray - Array of times between et_start and et_end. - - Returns - ------- - q_avg : np.ndarray - Average quaternion. - """ - aggregate = np.zeros((4, 4)) - for tdb in et_times: - # we use a quick and dirty method here for grabbing the quaternions - # from the attitude kernel. Depending on how well the kernel input - # data is built and sampled, there may or may not be aliasing with this - # approach. If it turns out that we need to pull the quaternions - # directly from the CK there are several routines that exist to do this - # but it's not straight forward. We'll revisit this if needed. - - # Rotation matrix from IMAP spacecraft frame to ECLIPJ2000. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.pxform - body_rots = spice.pxform("IMAP_SPACECRAFT", "ECLIPJ2000", tdb) - # Convert rotation matrix to quaternion. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.m2q - body_quat = spice.m2q(body_rots) - - # Standardize the quaternion so that they may be compared. - body_quat = body_quat * np.sign(body_quat[0]) - # Aggregate quaternions into a single matrix. - aggregate += np.outer(body_quat, body_quat) - - # Reference: "On Averaging Rotations" - # Link: https://link.springer.com/content/pdf/10.1023/A:1011129215388.pdf - aggregate /= len(et_times) - - # Compute eigen values and vectors of the matrix A - # Eigenvalues tell you how much "influence" each - # direction (eigenvector) has. - # The largest eigenvalue corresponds to the direction - # that has the most influence. - # The eigenvector corresponding to the largest - # eigenvalue points in the direction that has the most - # combined rotation influence. - eigvals, eigvecs = np.linalg.eig(aggregate) - # q0: The scalar part of the quaternion. - # q1, q2, q3: The vector part of the quaternion. - q_avg = eigvecs[:, np.argmax(eigvals)] - - return q_avg - - -def create_rotation_matrix(et_times: np.ndarray) -> NDArray: - """ - Create a rotation matrix. - - Parameters - ---------- - et_times : numpy.ndarray - Array of times between et_start and et_end. - - Returns - ------- - rotation_matrix : np.ndarray - Rotation matrix. - """ - # Averaged quaternions. - q_avg = average_quaternions(et_times) - - # Converts the averaged quaternion (q_avg) into a rotation matrix - # and get inertial z axis. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.q2m - z_avg = spice.q2m(list(q_avg))[:, 2] - # y_avg is perpendicular to both z_avg and the standard Z-axis. - y_avg = np.cross(z_avg, [0, 0, 1]) - # x_avg is perpendicular to y_avg and z_avg. - x_avg = np.cross(y_avg, z_avg) - - # Construct the rotation matrix from x_avg, y_avg, z_avg - rotation_matrix = np.asarray([x_avg, y_avg, z_avg]) - - return rotation_matrix - - -def create_pointing_frame() -> Path: - """ - Create the pointing frame. - - Returns - ------- - path_to_pointing_frame : Path - Path to dps frame. - """ - # TODO: this part will change with ensure_spice decorator. - # Mount path to EFS. - mount_path = Path(os.getenv("EFS_MOUNT_PATH", "")) - - # TODO: this part will change with ensure_spice decorator. - kernels = [str(file) for file in mount_path.iterdir()] - ck_kernel = [str(file) for file in mount_path.iterdir() if file.suffix == ".bc"] - - # Furnish the kernels. - with spice.KernelPool(kernels): - # Get timerange for the pointing frame kernel. - et_start, et_end, et_times = get_et_times(str(ck_kernel[0])) - # Create a rotation matrix - rotation_matrix = create_rotation_matrix(et_times) - - # Convert the rotation matrix to a quaternion. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.m2q - q_avg = spice.m2q(rotation_matrix) - - # TODO: come up with naming convention. - path_to_pointing_frame = mount_path / "imap_dps.bc" - - # Open a new CK file, returning the handle of the opened file. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckopn - handle = spice.ckopn(str(path_to_pointing_frame), "CK", 0) - # Get the SCLK ID. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool - id_imap_sclk = spice.gipool("CK_-43000_SCLK", 0, 1) - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.sce2c - # Convert start and end times to SCLK. - sclk_begtim = spice.sce2c(int(id_imap_sclk), et_start) - sclk_endtim = spice.sce2c(int(id_imap_sclk), et_end) - - # Get the pointing frame ID. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool - id_imap_dps = spice.gipool("FRAME_IMAP_DPS", 0, 1) - - # Create the pointing frame kernel. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckw02 - spice.ckw02( - # Handle of an open CK file. - handle, - # Start time of the segment. - sclk_begtim, - # End time of the segment. - sclk_endtim, - # Pointing frame ID. - int(id_imap_dps), - # Reference frame. - "ECLIPJ2000", # Reference frame - # Identifier. - "IMAP_DPS", - # Number of pointing intervals. - 1, - # Start times of individual pointing records within segment. - # Since there is only a single record this is equal to sclk_begtim. - np.array([sclk_begtim]), - # End times of individual pointing records within segment. - # Since there is only a single record this is equal to sclk_endtim. - np.array([sclk_endtim]), # Single stop time - # Average quaternion. - q_avg, - # 0.0 Angular rotation terms. - np.array([0.0, 0.0, 0.0]), - # Rates (seconds per tick) at which the quaternion and - # angular velocity change. - np.array([1.0]), - ) - - # Close CK file. - spice.ckcls(handle) - - return path_to_pointing_frame diff --git a/imap_processing/tests/spice/test_pointing_frame_handler.py b/imap_processing/tests/spice/test_pointing_frame_handler.py deleted file mode 100644 index 8972d061f..000000000 --- a/imap_processing/tests/spice/test_pointing_frame_handler.py +++ /dev/null @@ -1,106 +0,0 @@ -"""Tests Pointing Frame Generation.""" - -import os - -import numpy as np -import pytest -import spiceypy as spice - -from imap_processing.spice.pointing_frame_handler import ( - average_quaternions, - create_pointing_frame, - create_rotation_matrix, - get_et_times, -) - - -@pytest.fixture() -def kernels(spice_test_data_path): - """Create kernel list.""" - kernels = [str(file) for file in spice_test_data_path.iterdir()] - - return kernels - - -@pytest.fixture() -def ck_kernel(spice_test_data_path): - """Location of ck kernel to create pointing kernel from.""" - return spice_test_data_path / "imap_spin.bc" - - -@pytest.fixture() -def et_times(ck_kernel, kernels): - """Tests get_et_times function.""" - - with spice.KernelPool(kernels): - et_start, et_end, et_times = get_et_times(str(ck_kernel)) - - return et_times - - -def test_get_et_times(kernels, ck_kernel): - """Tests get_et_times function.""" - - with spice.KernelPool(kernels): - et_start, et_end, et_times = get_et_times(str(ck_kernel)) - - assert et_start == 802008069.184905 - assert et_end == 802015267.184906 - assert et_times[0] == et_start - assert et_times[-1] == et_end - - -def test_average_quaternions(et_times, kernels): - """Tests average_quaternions function.""" - - with spice.KernelPool(kernels): - q_avg = average_quaternions(et_times) - - # Generated from MATLAB code results - q_avg_expected = np.array([-0.6611, 0.4981, -0.5019, -0.2509]) - np.testing.assert_allclose(q_avg, q_avg_expected, atol=1e-4) - - -def test_create_rotation_matrix(et_times, kernels): - """Tests create_rotation_matrix function.""" - - with spice.KernelPool(kernels): - rotation_matrix = create_rotation_matrix(et_times) - q_avg = average_quaternions(et_times) - z_avg = spice.q2m(list(q_avg))[:, 2] - - rotation_matrix_expected = np.array( - [[0.0000, 0.0000, 1.0000], [0.9104, -0.4136, 0.0000], [0.4136, 0.9104, 0.0000]] - ) - z_avg_expected = np.array([0.4136, 0.9104, 0.0000]) - - np.testing.assert_allclose(z_avg, z_avg_expected, atol=1e-4) - np.testing.assert_allclose(rotation_matrix, rotation_matrix_expected, atol=1e-4) - - -def test_create_pointing_frame(monkeypatch, spice_test_data_path, ck_kernel, tmp_path): - """Tests create_pointing_frame function.""" - monkeypatch.setenv("EFS_MOUNT_PATH", str(spice_test_data_path)) - create_pointing_frame() - - # After imap_dps.bc has been created. - kernels = [str(file) for file in spice_test_data_path.iterdir()] - - with spice.KernelPool(kernels): - et_start, et_end, et_times = get_et_times(str(ck_kernel)) - - rotation_matrix_1 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 100) - rotation_matrix_2 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 1000) - - # All the rotation matrices should be the same. - assert np.array_equal(rotation_matrix_1, rotation_matrix_2) - - # Nick Dutton's MATLAB code result - rotation_matrix_expected = np.array( - [[0.0000, 0.0000, 1.0000], [0.9104, -0.4136, 0.0000], [0.4136, 0.9104, 0.0000]] - ) - np.testing.assert_allclose(rotation_matrix_1, rotation_matrix_expected, atol=1e-4) - - # Verify imap_dps.bc has been created. - assert (spice_test_data_path / "imap_dps.bc").exists() - os.remove(spice_test_data_path / "imap_dps.bc") From f2d83194557ac093ad1625b5f738683f886b0b98 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Thu, 22 Aug 2024 15:21:45 -0600 Subject: [PATCH 25/32] change docstring --- imap_processing/tests/spice/test_kernels.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap_processing/tests/spice/test_kernels.py b/imap_processing/tests/spice/test_kernels.py index 63155f875..708fbdf85 100644 --- a/imap_processing/tests/spice/test_kernels.py +++ b/imap_processing/tests/spice/test_kernels.py @@ -18,7 +18,7 @@ @pytest.fixture() def kernels(spice_test_data_path): - """Furnish SPICE kernels for the entire test module.""" + """List SPICE kernels.""" kernels = [str(file) for file in spice_test_data_path.iterdir()] return kernels From 5a41884ec8cbce16e4bd62ad68af554a85514352 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Thu, 22 Aug 2024 15:27:42 -0600 Subject: [PATCH 26/32] added todo --- imap_processing/tests/spice/test_kernels.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/imap_processing/tests/spice/test_kernels.py b/imap_processing/tests/spice/test_kernels.py index 708fbdf85..3694b5b5f 100644 --- a/imap_processing/tests/spice/test_kernels.py +++ b/imap_processing/tests/spice/test_kernels.py @@ -19,6 +19,7 @@ @pytest.fixture() def kernels(spice_test_data_path): """List SPICE kernels.""" + # TODO: remove this fixture after ensure_spice update. kernels = [str(file) for file in spice_test_data_path.iterdir()] return kernels @@ -26,6 +27,7 @@ def kernels(spice_test_data_path): @pytest.fixture() def et_times(kernels): """Tests get_et_times function.""" + # TODO: remove spice.furnsh(kernels) after ensure_spice update. spice.furnsh(kernels) file, _, _, _ = spice.kdata(0, "ck") @@ -103,6 +105,7 @@ def test_ensure_spice_key_error(): def test_average_quaternions(et_times, kernels): """Tests average_quaternions function.""" + # TODO: remove spice.furnsh(kernels) after ensure_spice update. spice.furnsh(kernels) q_avg = _average_quaternions(et_times) @@ -113,6 +116,7 @@ def test_average_quaternions(et_times, kernels): def test_create_rotation_matrix(et_times, kernels): """Tests create_rotation_matrix function.""" + # TODO: remove spice.furnsh(kernels) after ensure_spice update. spice.furnsh(kernels) rotation_matrix = _create_rotation_matrix(et_times) q_avg = _average_quaternions(et_times) @@ -129,6 +133,7 @@ def test_create_rotation_matrix(et_times, kernels): def test_create_pointing_frame(spice_test_data_path, kernels): """Tests create_pointing_frame function.""" + # TODO: remove spice.furnsh(kernels) after ensure_spice update. spice.furnsh(kernels) ck_kernel, _, _, _ = spice.kdata(0, "ck") et_start, et_end, et_times = _get_et_times(ck_kernel) From 42ce81b283421f5bea86895ca3929b87f9a0461e Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Thu, 22 Aug 2024 15:37:13 -0600 Subject: [PATCH 27/32] added tmp path --- imap_processing/spice/kernels.py | 12 ++++++++++-- imap_processing/tests/spice/test_kernels.py | 11 ++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/imap_processing/spice/kernels.py b/imap_processing/spice/kernels.py index 5e906df9e..35382ef20 100644 --- a/imap_processing/spice/kernels.py +++ b/imap_processing/spice/kernels.py @@ -162,10 +162,15 @@ def wrapper_ensure_spice(*args: Any, **kwargs: Any) -> Any: @ensure_spice -def create_pointing_frame() -> Path: +def create_pointing_frame(pointing_frame_dir: Optional[Path] = None) -> Path: """ Create the pointing frame. + Parameters + ---------- + pointing_frame_dir : Path + Directory of where pointing frame will be saved. + Returns ------- path_to_pointing_frame : Path @@ -184,7 +189,10 @@ def create_pointing_frame() -> Path: q_avg = spice.m2q(rotation_matrix) # TODO: come up with naming convention. - path_to_pointing_frame = directory / "imap_dps.bc" + if pointing_frame_dir is None: + path_to_pointing_frame = directory / "imap_dps.bc" + else: + path_to_pointing_frame = pointing_frame_dir / "imap_dps.bc" # Open a new CK file, returning the handle of the opened file. # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckopn diff --git a/imap_processing/tests/spice/test_kernels.py b/imap_processing/tests/spice/test_kernels.py index 3694b5b5f..ba8c069db 100644 --- a/imap_processing/tests/spice/test_kernels.py +++ b/imap_processing/tests/spice/test_kernels.py @@ -1,7 +1,5 @@ """Tests coverage for imap_processing/spice/kernels.py""" -import os - import numpy as np import pytest import spiceypy as spice @@ -131,16 +129,16 @@ def test_create_rotation_matrix(et_times, kernels): np.testing.assert_allclose(rotation_matrix, rotation_matrix_expected, atol=1e-4) -def test_create_pointing_frame(spice_test_data_path, kernels): +def test_create_pointing_frame(spice_test_data_path, kernels, tmp_path): """Tests create_pointing_frame function.""" # TODO: remove spice.furnsh(kernels) after ensure_spice update. spice.furnsh(kernels) ck_kernel, _, _, _ = spice.kdata(0, "ck") et_start, et_end, et_times = _get_et_times(ck_kernel) - create_pointing_frame() + create_pointing_frame(pointing_frame_dir=tmp_path) # After imap_dps.bc has been created. - dps_kernel = str(spice_test_data_path / "imap_dps.bc") + dps_kernel = str(tmp_path / "imap_dps.bc") spice.furnsh(dps_kernel) rotation_matrix_1 = spice.pxform("ECLIPJ2000", "IMAP_DPS", et_start + 100) @@ -156,5 +154,4 @@ def test_create_pointing_frame(spice_test_data_path, kernels): np.testing.assert_allclose(rotation_matrix_1, rotation_matrix_expected, atol=1e-4) # Verify imap_dps.bc has been created. - assert (spice_test_data_path / "imap_dps.bc").exists() - os.remove(spice_test_data_path / "imap_dps.bc") + assert (tmp_path / "imap_dps.bc").exists() From d308c412d3e6e5c275cdbbbd9b0629ba95cc709a Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Thu, 22 Aug 2024 15:59:31 -0600 Subject: [PATCH 28/32] add todo; exit --- imap_processing/spice/kernels.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap_processing/spice/kernels.py b/imap_processing/spice/kernels.py index 35382ef20..4022beb64 100644 --- a/imap_processing/spice/kernels.py +++ b/imap_processing/spice/kernels.py @@ -208,7 +208,7 @@ def create_pointing_frame(pointing_frame_dir: Optional[Path] = None) -> Path: # Get the pointing frame ID. # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool id_imap_dps = spice.gipool("FRAME_IMAP_DPS", 0, 1) - + # TODO: Figure out how to write new pointings to same CK kernel. # Create the pointing frame kernel. # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckw02 spice.ckw02( From bcb2d9c5da802a3bb5c2f8856e4f0472d8e8b4ec Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Mon, 26 Aug 2024 17:01:59 -0600 Subject: [PATCH 29/32] rename --- ...> imap_sim_ck_2hr_2secsampling_with_nutation.bc} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename imap_processing/tests/spice/test_data/{imap_spin.bc => imap_sim_ck_2hr_2secsampling_with_nutation.bc} (100%) diff --git a/imap_processing/tests/spice/test_data/imap_spin.bc b/imap_processing/tests/spice/test_data/imap_sim_ck_2hr_2secsampling_with_nutation.bc similarity index 100% rename from imap_processing/tests/spice/test_data/imap_spin.bc rename to imap_processing/tests/spice/test_data/imap_sim_ck_2hr_2secsampling_with_nutation.bc From aa8feacd139d808e751c06132c69ba6e85e13290 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Mon, 26 Aug 2024 17:05:24 -0600 Subject: [PATCH 30/32] pr response --- imap_processing/spice/kernels.py | 23 ++++----- imap_processing/tests/spice/test_kernels.py | 55 +++++++++++++-------- 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/imap_processing/spice/kernels.py b/imap_processing/spice/kernels.py index 4022beb64..fa7e7e5a7 100644 --- a/imap_processing/spice/kernels.py +++ b/imap_processing/spice/kernels.py @@ -162,22 +162,25 @@ def wrapper_ensure_spice(*args: Any, **kwargs: Any) -> Any: @ensure_spice -def create_pointing_frame(pointing_frame_dir: Optional[Path] = None) -> Path: +def create_pointing_frame(pointing_frame_path: Optional[Path] = None) -> Path: """ Create the pointing frame. Parameters ---------- - pointing_frame_dir : Path + pointing_frame_path : Path Directory of where pointing frame will be saved. Returns ------- - path_to_pointing_frame : Path + pointing_frame_path : Path Path to pointing frame. + + References + ---------- + https://numpydoc.readthedocs.io/en/latest/format.html#references """ ck_kernel, _, _, _ = spice.kdata(0, "ck") - directory = Path(ck_kernel).parent # Get timerange for the pointing frame kernel. et_start, et_end, et_times = _get_et_times(ck_kernel) @@ -189,14 +192,12 @@ def create_pointing_frame(pointing_frame_dir: Optional[Path] = None) -> Path: q_avg = spice.m2q(rotation_matrix) # TODO: come up with naming convention. - if pointing_frame_dir is None: - path_to_pointing_frame = directory / "imap_dps.bc" - else: - path_to_pointing_frame = pointing_frame_dir / "imap_dps.bc" + if pointing_frame_path is None: + pointing_frame_path = Path(ck_kernel).parent / "imap_dps.bc" # Open a new CK file, returning the handle of the opened file. # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckopn - handle = spice.ckopn(str(path_to_pointing_frame), "CK", 0) + handle = spice.ckopn(str(pointing_frame_path), "CK", 0) # Get the SCLK ID. # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool id_imap_sclk = spice.gipool("CK_-43000_SCLK", 0, 1) @@ -244,7 +245,7 @@ def create_pointing_frame(pointing_frame_dir: Optional[Path] = None) -> Path: # Close CK file. spice.ckcls(handle) - return path_to_pointing_frame + return pointing_frame_path @ensure_spice @@ -271,6 +272,7 @@ def _get_et_times(ck_kernel: str) -> tuple[float, float, np.ndarray]: id_imap_spacecraft = spice.gipool("FRAME_IMAP_SPACECRAFT", 0, 1) # TODO: Queried pointing start and stop times here. + # TODO removing the @ensure_spice decorator when using the repointing table. # Get the coverage window # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckcov @@ -340,7 +342,6 @@ def _average_quaternions(et_times: np.ndarray) -> NDArray: return q_avg -@ensure_spice def _create_rotation_matrix(et_times: np.ndarray) -> NDArray: """ Create a rotation matrix. diff --git a/imap_processing/tests/spice/test_kernels.py b/imap_processing/tests/spice/test_kernels.py index ba8c069db..0edddeaba 100644 --- a/imap_processing/tests/spice/test_kernels.py +++ b/imap_processing/tests/spice/test_kernels.py @@ -15,27 +15,27 @@ @pytest.fixture() -def kernels(spice_test_data_path): +def pointing_frame_kernels(spice_test_data_path): """List SPICE kernels.""" - # TODO: remove this fixture after ensure_spice update. - kernels = [str(file) for file in spice_test_data_path.iterdir()] + required_kernels = [ + "imap_science_0001.tf", + "imap_sclk_0000.tsc", + "imap_sim_ck_2hr_2secsampling_with_nutation.bc", + "imap_wkcp.tf", + "naif0012.tls", + ] + kernels = [str(spice_test_data_path / kernel) for kernel in required_kernels] return kernels @pytest.fixture() -def et_times(kernels): +def et_times(pointing_frame_kernels): """Tests get_et_times function.""" - # TODO: remove spice.furnsh(kernels) after ensure_spice update. - spice.furnsh(kernels) + spice.furnsh(pointing_frame_kernels) file, _, _, _ = spice.kdata(0, "ck") et_start, et_end, et_times = _get_et_times(file) - assert et_start == 802008069.184905 - assert et_end == 802015267.184906 - assert et_times[0] == et_start - assert et_times[-1] == et_end - return et_times @@ -101,10 +101,9 @@ def test_ensure_spice_key_error(): _ = wrapped(577365941.184, "ISOC", 3) == "2018-04-18T23:24:31.998" -def test_average_quaternions(et_times, kernels): +def test_average_quaternions(et_times, pointing_frame_kernels): """Tests average_quaternions function.""" - # TODO: remove spice.furnsh(kernels) after ensure_spice update. - spice.furnsh(kernels) + spice.furnsh(pointing_frame_kernels) q_avg = _average_quaternions(et_times) # Generated from MATLAB code results @@ -112,10 +111,9 @@ def test_average_quaternions(et_times, kernels): np.testing.assert_allclose(q_avg, q_avg_expected, atol=1e-4) -def test_create_rotation_matrix(et_times, kernels): +def test_create_rotation_matrix(et_times, pointing_frame_kernels): """Tests create_rotation_matrix function.""" - # TODO: remove spice.furnsh(kernels) after ensure_spice update. - spice.furnsh(kernels) + spice.furnsh(pointing_frame_kernels) rotation_matrix = _create_rotation_matrix(et_times) q_avg = _average_quaternions(et_times) z_avg = spice.q2m(list(q_avg))[:, 2] @@ -129,13 +127,12 @@ def test_create_rotation_matrix(et_times, kernels): np.testing.assert_allclose(rotation_matrix, rotation_matrix_expected, atol=1e-4) -def test_create_pointing_frame(spice_test_data_path, kernels, tmp_path): +def test_create_pointing_frame(spice_test_data_path, pointing_frame_kernels, tmp_path): """Tests create_pointing_frame function.""" - # TODO: remove spice.furnsh(kernels) after ensure_spice update. - spice.furnsh(kernels) + spice.furnsh(pointing_frame_kernels) ck_kernel, _, _, _ = spice.kdata(0, "ck") et_start, et_end, et_times = _get_et_times(ck_kernel) - create_pointing_frame(pointing_frame_dir=tmp_path) + create_pointing_frame(pointing_frame_path=tmp_path / "imap_dps.bc") # After imap_dps.bc has been created. dps_kernel = str(tmp_path / "imap_dps.bc") @@ -155,3 +152,19 @@ def test_create_pointing_frame(spice_test_data_path, kernels, tmp_path): # Verify imap_dps.bc has been created. assert (tmp_path / "imap_dps.bc").exists() + + +@ensure_spice +def test_et_times(pointing_frame_kernels): + """Tests get_et_times function.""" + spice.furnsh(pointing_frame_kernels) + + file, _, _, _ = spice.kdata(0, "ck") + et_start, et_end, et_times = _get_et_times(file) + + assert et_start == 802008069.184905 + assert et_end == 802015267.184906 + assert et_times[0] == et_start + assert et_times[-1] == et_end + + return et_times From e36b90f115a63458df4738550ffdaa24f0229a19 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 27 Aug 2024 09:48:51 -0600 Subject: [PATCH 31/32] pr response --- imap_processing/spice/kernels.py | 116 +++-- poetry.lock | 761 +++++++++++++++---------------- 2 files changed, 431 insertions(+), 446 deletions(-) diff --git a/imap_processing/spice/kernels.py b/imap_processing/spice/kernels.py index fa7e7e5a7..6830de06b 100644 --- a/imap_processing/spice/kernels.py +++ b/imap_processing/spice/kernels.py @@ -1,10 +1,11 @@ """Functions for furnishing and tracking SPICE kernels.""" +from contextlib import contextmanager import functools import logging import os from pathlib import Path -from typing import Any, Callable, Optional +from typing import Any, Callable, Optional, Generator import numpy as np import spiceypy as spice @@ -161,6 +162,28 @@ def wrapper_ensure_spice(*args: Any, **kwargs: Any) -> Any: return _decorator +@contextmanager +def spice_ck_file(pointing_frame_path: str) -> Generator[int, None, None]: + """ + Context manager for handling SPICE CK files. + + Parameters + ---------- + pointing_frame_path : str + Path to the CK file. + + Yields + ------ + handle : int + Handle to the opened CK file. + """ + handle = spice.ckopn(pointing_frame_path, "CK", 0) + try: + yield handle + finally: + spice.ckcls(handle) + + @ensure_spice def create_pointing_frame(pointing_frame_path: Optional[Path] = None) -> Path: """ @@ -197,53 +220,50 @@ def create_pointing_frame(pointing_frame_path: Optional[Path] = None) -> Path: # Open a new CK file, returning the handle of the opened file. # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckopn - handle = spice.ckopn(str(pointing_frame_path), "CK", 0) - # Get the SCLK ID. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool - id_imap_sclk = spice.gipool("CK_-43000_SCLK", 0, 1) - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.sce2c - # Convert start and end times to SCLK. - sclk_begtim = spice.sce2c(int(id_imap_sclk), et_start) - sclk_endtim = spice.sce2c(int(id_imap_sclk), et_end) - - # Get the pointing frame ID. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool - id_imap_dps = spice.gipool("FRAME_IMAP_DPS", 0, 1) - # TODO: Figure out how to write new pointings to same CK kernel. - # Create the pointing frame kernel. - # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckw02 - spice.ckw02( - # Handle of an open CK file. - handle, - # Start time of the segment. - sclk_begtim, - # End time of the segment. - sclk_endtim, - # Pointing frame ID. - int(id_imap_dps), - # Reference frame. - "ECLIPJ2000", # Reference frame - # Identifier. - "IMAP_DPS", - # Number of pointing intervals. - 1, - # Start times of individual pointing records within segment. - # Since there is only a single record this is equal to sclk_begtim. - np.array([sclk_begtim]), - # End times of individual pointing records within segment. - # Since there is only a single record this is equal to sclk_endtim. - np.array([sclk_endtim]), # Single stop time - # Average quaternion. - q_avg, - # 0.0 Angular rotation terms. - np.array([0.0, 0.0, 0.0]), - # Rates (seconds per tick) at which the quaternion and - # angular velocity change. - np.array([1.0]), - ) - - # Close CK file. - spice.ckcls(handle) + with spice_ck_file(str(pointing_frame_path)) as handle: + # Get the SCLK ID. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool + id_imap_sclk = spice.gipool("CK_-43000_SCLK", 0, 1) + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.sce2c + # Convert start and end times to SCLK. + sclk_begtim = spice.sce2c(int(id_imap_sclk), et_start) + sclk_endtim = spice.sce2c(int(id_imap_sclk), et_end) + + # Get the pointing frame ID. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.gipool + id_imap_dps = spice.gipool("FRAME_IMAP_DPS", 0, 1) + # TODO: Figure out how to write new pointings to same CK kernel. + # Create the pointing frame kernel. + # https://spiceypy.readthedocs.io/en/main/documentation.html#spiceypy.spiceypy.ckw02 + spice.ckw02( + # Handle of an open CK file. + handle, + # Start time of the segment. + sclk_begtim, + # End time of the segment. + sclk_endtim, + # Pointing frame ID. + int(id_imap_dps), + # Reference frame. + "ECLIPJ2000", # Reference frame + # Identifier. + "IMAP_DPS", + # Number of pointing intervals. + 1, + # Start times of individual pointing records within segment. + # Since there is only a single record this is equal to sclk_begtim. + np.array([sclk_begtim]), + # End times of individual pointing records within segment. + # Since there is only a single record this is equal to sclk_endtim. + np.array([sclk_endtim]), # Single stop time + # Average quaternion. + q_avg, + # 0.0 Angular rotation terms. + np.array([0.0, 0.0, 0.0]), + # Rates (seconds per tick) at which the quaternion and + # angular velocity change. + np.array([1.0]), + ) return pointing_frame_path diff --git a/poetry.lock b/poetry.lock index ff98390a2..83c5479d1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.0 and should not be changed by hand. [[package]] name = "accessible-pygments" @@ -31,32 +31,32 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "23.2.0" description = "Classes Without Boilerplate" optional = true python-versions = ">=3.7" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] [package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] [[package]] name = "babel" -version = "2.16.0" +version = "2.15.0" description = "Internationalization utilities" optional = true python-versions = ">=3.8" files = [ - {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, - {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, + {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, + {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, ] [package.extras] @@ -248,13 +248,13 @@ tests = ["astropy", "hypothesis", "pytest (>=3.9)", "pytest-cov", "pytest-remote [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.6.2" description = "Python package for providing Mozilla's CA Bundle." optional = true python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, + {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, ] [[package]] @@ -380,83 +380,63 @@ files = [ [[package]] name = "coverage" -version = "7.6.1" +version = "7.5.4" description = "Code coverage measurement for Python" optional = true python-versions = ">=3.8" files = [ - {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, - {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, - {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, - {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, - {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, - {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, - {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, - {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, - {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, - {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, - {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, - {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, - {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, - {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, - {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, - {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, - {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, - {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, - {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, - {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, - {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, - {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, - {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, - {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, - {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, - {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, - {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, - {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, - {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, - {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, + {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, + {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, + {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, + {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, + {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, + {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, + {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, + {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, + {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, + {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, + {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, + {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, + {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, + {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, + {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, + {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, + {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, + {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, + {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, + {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, + {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, + {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, ] [package.dependencies] @@ -511,13 +491,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.2" +version = "1.2.1" description = "Backport of PEP 654 (exception groups)" optional = true python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, + {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, + {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, ] [package.extras] @@ -541,13 +521,13 @@ typing = ["typing-extensions (>=4.8)"] [[package]] name = "identify" -version = "2.6.0" +version = "2.5.36" description = "File identification library for Python" optional = true python-versions = ">=3.8" files = [ - {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"}, - {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"}, + {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, + {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, ] [package.extras] @@ -577,12 +557,12 @@ files = [ [[package]] name = "imap-data-access" -version = "0.9.0" +version = "0.7.0" description = "IMAP SDC Data Access" optional = false python-versions = "*" files = [ - {file = "imap_data_access-0.9.0.tar.gz", hash = "sha256:997084118c85455d1c977d5640a8654717a1f8adf39eaeccfc3e124b5efd3c4f"}, + {file = "imap_data_access-0.7.0.tar.gz", hash = "sha256:f0db935949d048394fc554b308b1e4a1572a18acd41636462d37c309c7cb4c9d"}, ] [package.extras] @@ -591,13 +571,13 @@ test = ["pytest", "pytest-cov"] [[package]] name = "importlib-metadata" -version = "8.4.0" +version = "8.0.0" description = "Read metadata from Python packages" optional = true python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"}, - {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"}, + {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, + {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, ] [package.dependencies] @@ -638,13 +618,13 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsonschema" -version = "4.23.0" +version = "4.22.0" description = "An implementation of JSON Schema validation for Python" optional = true python-versions = ">=3.8" files = [ - {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, - {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, + {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, + {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, ] [package.dependencies] @@ -655,7 +635,7 @@ rpds-py = ">=0.7.1" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] name = "jsonschema-specifications" @@ -753,44 +733,44 @@ files = [ [[package]] name = "mypy" -version = "1.11.1" +version = "1.10.1" description = "Optional static typing for Python" optional = true python-versions = ">=3.8" files = [ - {file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"}, - {file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"}, - {file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"}, - {file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"}, - {file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"}, - {file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"}, - {file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"}, - {file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"}, - {file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"}, - {file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"}, - {file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"}, - {file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"}, - {file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"}, - {file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"}, - {file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"}, - {file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"}, - {file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"}, - {file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"}, - {file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, + {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, + {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, + {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, + {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, + {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, + {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, + {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, + {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, + {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, + {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, + {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, + {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, + {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, + {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, + {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, + {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, + {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, ] [package.dependencies] mypy-extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.6.0" +typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] @@ -822,67 +802,58 @@ files = [ [[package]] name = "numpy" -version = "2.0.1" +version = "1.26.4" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.9" files = [ - {file = "numpy-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fbb536eac80e27a2793ffd787895242b7f18ef792563d742c2d673bfcb75134"}, - {file = "numpy-2.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:69ff563d43c69b1baba77af455dd0a839df8d25e8590e79c90fcbe1499ebde42"}, - {file = "numpy-2.0.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:1b902ce0e0a5bb7704556a217c4f63a7974f8f43e090aff03fcf262e0b135e02"}, - {file = "numpy-2.0.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:f1659887361a7151f89e79b276ed8dff3d75877df906328f14d8bb40bb4f5101"}, - {file = "numpy-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4658c398d65d1b25e1760de3157011a80375da861709abd7cef3bad65d6543f9"}, - {file = "numpy-2.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4127d4303b9ac9f94ca0441138acead39928938660ca58329fe156f84b9f3015"}, - {file = "numpy-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e5eeca8067ad04bc8a2a8731183d51d7cbaac66d86085d5f4766ee6bf19c7f87"}, - {file = "numpy-2.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9adbd9bb520c866e1bfd7e10e1880a1f7749f1f6e5017686a5fbb9b72cf69f82"}, - {file = "numpy-2.0.1-cp310-cp310-win32.whl", hash = "sha256:7b9853803278db3bdcc6cd5beca37815b133e9e77ff3d4733c247414e78eb8d1"}, - {file = "numpy-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:81b0893a39bc5b865b8bf89e9ad7807e16717f19868e9d234bdaf9b1f1393868"}, - {file = "numpy-2.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75b4e316c5902d8163ef9d423b1c3f2f6252226d1aa5cd8a0a03a7d01ffc6268"}, - {file = "numpy-2.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6e4eeb6eb2fced786e32e6d8df9e755ce5be920d17f7ce00bc38fcde8ccdbf9e"}, - {file = "numpy-2.0.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a1e01dcaab205fbece13c1410253a9eea1b1c9b61d237b6fa59bcc46e8e89343"}, - {file = "numpy-2.0.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a8fc2de81ad835d999113ddf87d1ea2b0f4704cbd947c948d2f5513deafe5a7b"}, - {file = "numpy-2.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a3d94942c331dd4e0e1147f7a8699a4aa47dffc11bf8a1523c12af8b2e91bbe"}, - {file = "numpy-2.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15eb4eca47d36ec3f78cde0a3a2ee24cf05ca7396ef808dda2c0ddad7c2bde67"}, - {file = "numpy-2.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b83e16a5511d1b1f8a88cbabb1a6f6a499f82c062a4251892d9ad5d609863fb7"}, - {file = "numpy-2.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f87fec1f9bc1efd23f4227becff04bd0e979e23ca50cc92ec88b38489db3b55"}, - {file = "numpy-2.0.1-cp311-cp311-win32.whl", hash = "sha256:36d3a9405fd7c511804dc56fc32974fa5533bdeb3cd1604d6b8ff1d292b819c4"}, - {file = "numpy-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:08458fbf403bff5e2b45f08eda195d4b0c9b35682311da5a5a0a0925b11b9bd8"}, - {file = "numpy-2.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6bf4e6f4a2a2e26655717a1983ef6324f2664d7011f6ef7482e8c0b3d51e82ac"}, - {file = "numpy-2.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6fddc5fe258d3328cd8e3d7d3e02234c5d70e01ebe377a6ab92adb14039cb4"}, - {file = "numpy-2.0.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:5daab361be6ddeb299a918a7c0864fa8618af66019138263247af405018b04e1"}, - {file = "numpy-2.0.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:ea2326a4dca88e4a274ba3a4405eb6c6467d3ffbd8c7d38632502eaae3820587"}, - {file = "numpy-2.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:529af13c5f4b7a932fb0e1911d3a75da204eff023ee5e0e79c1751564221a5c8"}, - {file = "numpy-2.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6790654cb13eab303d8402354fabd47472b24635700f631f041bd0b65e37298a"}, - {file = "numpy-2.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbab9fc9c391700e3e1287666dfd82d8666d10e69a6c4a09ab97574c0b7ee0a7"}, - {file = "numpy-2.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:99d0d92a5e3613c33a5f01db206a33f8fdf3d71f2912b0de1739894668b7a93b"}, - {file = "numpy-2.0.1-cp312-cp312-win32.whl", hash = "sha256:173a00b9995f73b79eb0191129f2455f1e34c203f559dd118636858cc452a1bf"}, - {file = "numpy-2.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:bb2124fdc6e62baae159ebcfa368708867eb56806804d005860b6007388df171"}, - {file = "numpy-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bfc085b28d62ff4009364e7ca34b80a9a080cbd97c2c0630bb5f7f770dae9414"}, - {file = "numpy-2.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8fae4ebbf95a179c1156fab0b142b74e4ba4204c87bde8d3d8b6f9c34c5825ef"}, - {file = "numpy-2.0.1-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:72dc22e9ec8f6eaa206deb1b1355eb2e253899d7347f5e2fae5f0af613741d06"}, - {file = "numpy-2.0.1-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:ec87f5f8aca726117a1c9b7083e7656a9d0d606eec7299cc067bb83d26f16e0c"}, - {file = "numpy-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f682ea61a88479d9498bf2091fdcd722b090724b08b31d63e022adc063bad59"}, - {file = "numpy-2.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8efc84f01c1cd7e34b3fb310183e72fcdf55293ee736d679b6d35b35d80bba26"}, - {file = "numpy-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3fdabe3e2a52bc4eff8dc7a5044342f8bd9f11ef0934fcd3289a788c0eb10018"}, - {file = "numpy-2.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:24a0e1befbfa14615b49ba9659d3d8818a0f4d8a1c5822af8696706fbda7310c"}, - {file = "numpy-2.0.1-cp39-cp39-win32.whl", hash = "sha256:f9cf5ea551aec449206954b075db819f52adc1638d46a6738253a712d553c7b4"}, - {file = "numpy-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:e9e81fa9017eaa416c056e5d9e71be93d05e2c3c2ab308d23307a8bc4443c368"}, - {file = "numpy-2.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:61728fba1e464f789b11deb78a57805c70b2ed02343560456190d0501ba37b0f"}, - {file = "numpy-2.0.1-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:12f5d865d60fb9734e60a60f1d5afa6d962d8d4467c120a1c0cda6eb2964437d"}, - {file = "numpy-2.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eacf3291e263d5a67d8c1a581a8ebbcfd6447204ef58828caf69a5e3e8c75990"}, - {file = "numpy-2.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2c3a346ae20cfd80b6cfd3e60dc179963ef2ea58da5ec074fd3d9e7a1e7ba97f"}, - {file = "numpy-2.0.1.tar.gz", hash = "sha256:485b87235796410c3519a699cfe1faab097e509e90ebb05dcd098db2ae87e7b3"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] [[package]] name = "numpydoc" -version = "1.8.0" +version = "1.7.0" description = "Sphinx extension to support docstrings in Numpy format" optional = true -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "numpydoc-1.8.0-py3-none-any.whl", hash = "sha256:72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541"}, - {file = "numpydoc-1.8.0.tar.gz", hash = "sha256:022390ab7464a44f8737f79f8b31ce1d3cfa4b4af79ccaa1aac5e8368db587fb"}, + {file = "numpydoc-1.7.0-py3-none-any.whl", hash = "sha256:5a56419d931310d79a06cfc2a126d1558700feeb9b4f3d8dcae1a8134be829c9"}, + {file = "numpydoc-1.7.0.tar.gz", hash = "sha256:866e5ae5b6509dcf873fc6381120f5c31acf13b135636c1a81d68c166a95f921"}, ] [package.dependencies] @@ -892,7 +863,7 @@ tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} [package.extras] developer = ["pre-commit (>=3.3)", "tomli"] -doc = ["intersphinx-registry", "matplotlib (>=3.5)", "numpy (>=1.22)", "pydata-sphinx-theme (>=0.13.3)", "sphinx (>=7)"] +doc = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pydata-sphinx-theme (>=0.13.3)", "sphinx (>=7)"] test = ["matplotlib", "pytest", "pytest-cov"] [[package]] @@ -1037,13 +1008,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "3.8.0" +version = "3.7.1" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = true python-versions = ">=3.9" files = [ - {file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"}, - {file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"}, + {file = "pre_commit-3.7.1-py2.py3-none-any.whl", hash = "sha256:fae36fd1d7ad7d6a5a1c0b0d5adb2ed1a3bda5a21bf6c3e5372073d7a11cd4c5"}, + {file = "pre_commit-3.7.1.tar.gz", hash = "sha256:8ca3ad567bc78a4972a3f1a477e94a79d4597e8140a6e0b651c5e33899c3654a"}, ] [package.dependencies] @@ -1097,13 +1068,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pytest" -version = "8.3.2" +version = "8.2.2" description = "pytest: simple powerful testing with Python" optional = true python-versions = ">=3.8" files = [ - {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, - {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, + {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, + {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, ] [package.dependencies] @@ -1111,7 +1082,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.5,<2" +pluggy = ">=1.5,<2.0" tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] @@ -1162,64 +1133,62 @@ files = [ [[package]] name = "pyyaml" -version = "6.0.2" +version = "6.0.1" description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.6" files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] [[package]] @@ -1260,114 +1229,110 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rpds-py" -version = "0.20.0" +version = "0.18.1" description = "Python bindings to Rust's persistent data structures (rpds)" optional = true python-versions = ">=3.8" files = [ - {file = "rpds_py-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2"}, - {file = "rpds_py-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140"}, - {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f"}, - {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce"}, - {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94"}, - {file = "rpds_py-0.20.0-cp310-none-win32.whl", hash = "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee"}, - {file = "rpds_py-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399"}, - {file = "rpds_py-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489"}, - {file = "rpds_py-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3"}, - {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272"}, - {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad"}, - {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58"}, - {file = "rpds_py-0.20.0-cp311-none-win32.whl", hash = "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0"}, - {file = "rpds_py-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c"}, - {file = "rpds_py-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6"}, - {file = "rpds_py-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef"}, - {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821"}, - {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940"}, - {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174"}, - {file = "rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139"}, - {file = "rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585"}, - {file = "rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29"}, - {file = "rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f"}, - {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c"}, - {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2"}, - {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57"}, - {file = "rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a"}, - {file = "rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2"}, - {file = "rpds_py-0.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24"}, - {file = "rpds_py-0.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8"}, - {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e"}, - {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253"}, - {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a"}, - {file = "rpds_py-0.20.0-cp38-none-win32.whl", hash = "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5"}, - {file = "rpds_py-0.20.0-cp38-none-win_amd64.whl", hash = "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232"}, - {file = "rpds_py-0.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22"}, - {file = "rpds_py-0.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580"}, - {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b"}, - {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420"}, - {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b"}, - {file = "rpds_py-0.20.0-cp39-none-win32.whl", hash = "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7"}, - {file = "rpds_py-0.20.0-cp39-none-win_amd64.whl", hash = "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8"}, - {file = "rpds_py-0.20.0.tar.gz", hash = "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121"}, + {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"}, + {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"}, + {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"}, + {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"}, + {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"}, + {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"}, + {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"}, + {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"}, + {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"}, + {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"}, + {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"}, + {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"}, + {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"}, + {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"}, + {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"}, + {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"}, + {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"}, + {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"}, + {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"}, + {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"}, + {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, ] [[package]] @@ -1420,13 +1385,13 @@ files = [ [[package]] name = "soupsieve" -version = "2.6" +version = "2.5" description = "A modern CSS selector implementation for Beautiful Soup." optional = true python-versions = ">=3.8" files = [ - {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, - {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, ] [[package]] @@ -1445,27 +1410,27 @@ bitstring = ">=4.0.1" [[package]] name = "sphinx" -version = "7.4.7" +version = "7.3.7" description = "Python documentation generator" optional = true python-versions = ">=3.9" files = [ - {file = "sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239"}, - {file = "sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe"}, + {file = "sphinx-7.3.7-py3-none-any.whl", hash = "sha256:413f75440be4cacf328f580b4274ada4565fb2187d696a84970c23f77b64d8c3"}, + {file = "sphinx-7.3.7.tar.gz", hash = "sha256:a4a7db75ed37531c05002d56ed6948d4c42f473a36f46e1382b0bd76ca9627bc"}, ] [package.dependencies] alabaster = ">=0.7.14,<0.8.0" -babel = ">=2.13" -colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} -docutils = ">=0.20,<0.22" +babel = ">=2.9" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.18.1,<0.22" imagesize = ">=1.3" -importlib-metadata = {version = ">=6.0", markers = "python_version < \"3.10\""} -Jinja2 = ">=3.1" -packaging = ">=23.0" -Pygments = ">=2.17" -requests = ">=2.30.0" -snowballstemmer = ">=2.2" +importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} +Jinja2 = ">=3.0" +packaging = ">=21.0" +Pygments = ">=2.14" +requests = ">=2.25.0" +snowballstemmer = ">=2.0" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" sphinxcontrib-htmlhelp = ">=2.0.0" @@ -1476,22 +1441,22 @@ tomli = {version = ">=2", markers = "python_version < \"3.11\""} [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["flake8 (>=6.0)", "importlib-metadata (>=6.0)", "mypy (==1.10.1)", "pytest (>=6.0)", "ruff (==0.5.2)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-docutils (==0.21.0.20240711)", "types-requests (>=2.30.0)"] -test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"] +lint = ["flake8 (>=3.5.0)", "importlib_metadata", "mypy (==1.9.0)", "pytest (>=6.0)", "ruff (==0.3.7)", "sphinx-lint", "tomli", "types-docutils", "types-requests"] +test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=6.0)", "setuptools (>=67.0)"] [[package]] name = "sphinx-mdinclude" -version = "0.6.2" +version = "0.6.1" description = "Markdown extension for Sphinx" optional = true python-versions = ">=3.8" files = [ - {file = "sphinx_mdinclude-0.6.2-py3-none-any.whl", hash = "sha256:648e78edb067c0e4bffc22943278d49d54a0714494743592032fa3ad82a86984"}, - {file = "sphinx_mdinclude-0.6.2.tar.gz", hash = "sha256:447462e82cb8be61404a2204227f920769eb923d2f57608e3325f3bb88286b4c"}, + {file = "sphinx_mdinclude-0.6.1-py3-none-any.whl", hash = "sha256:d96cb01b8ab23dc8e5e3932c8fbc91d402e7e708aa5ba8d63a8e627d00275ae6"}, + {file = "sphinx_mdinclude-0.6.1.tar.gz", hash = "sha256:ece3d812e2d559b4e7e47f67b6a87b0e2a689b6b2f5114795c8ed47ffb39c169"}, ] [package.dependencies] -docutils = ">=0.19,<1.0" +docutils = ">=0.16,<1.0" mistune = ">=3.0,<4.0" pygments = ">=2.8" sphinx = ">=6" @@ -1501,49 +1466,49 @@ dev = ["attribution (==1.7.1)", "black (==24.4.2)", "coverage (==7.5.1)", "docut [[package]] name = "sphinxcontrib-applehelp" -version = "2.0.0" +version = "1.0.8" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, - {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, + {file = "sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4"}, + {file = "sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619"}, ] [package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +lint = ["docutils-stubs", "flake8", "mypy"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-devhelp" -version = "2.0.0" +version = "1.0.6" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, - {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, + {file = "sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f"}, + {file = "sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3"}, ] [package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +lint = ["docutils-stubs", "flake8", "mypy"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" -version = "2.1.0" +version = "2.0.5" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, - {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, + {file = "sphinxcontrib_htmlhelp-2.0.5-py3-none-any.whl", hash = "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04"}, + {file = "sphinxcontrib_htmlhelp-2.0.5.tar.gz", hash = "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015"}, ] [package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +lint = ["docutils-stubs", "flake8", "mypy"] standalone = ["Sphinx (>=5)"] test = ["html5lib", "pytest"] @@ -1598,33 +1563,33 @@ sphinxcontrib-httpdomain = ">=1.5.0" [[package]] name = "sphinxcontrib-qthelp" -version = "2.0.0" +version = "1.0.7" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, - {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, + {file = "sphinxcontrib_qthelp-1.0.7-py3-none-any.whl", hash = "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182"}, + {file = "sphinxcontrib_qthelp-1.0.7.tar.gz", hash = "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6"}, ] [package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +lint = ["docutils-stubs", "flake8", "mypy"] standalone = ["Sphinx (>=5)"] -test = ["defusedxml (>=0.7.1)", "pytest"] +test = ["pytest"] [[package]] name = "sphinxcontrib-serializinghtml" -version = "2.0.0" +version = "1.1.10" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" optional = true python-versions = ">=3.9" files = [ - {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, - {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, + {file = "sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7"}, + {file = "sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f"}, ] [package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +lint = ["docutils-stubs", "flake8", "mypy"] standalone = ["Sphinx (>=5)"] test = ["pytest"] @@ -1736,13 +1701,13 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess [[package]] name = "xarray" -version = "2024.7.0" +version = "2024.6.0" description = "N-D labeled arrays and datasets in Python" optional = false python-versions = ">=3.9" files = [ - {file = "xarray-2024.7.0-py3-none-any.whl", hash = "sha256:1b0fd51ec408474aa1f4a355d75c00cc1c02bd425d97b2c2e551fd21810e7f64"}, - {file = "xarray-2024.7.0.tar.gz", hash = "sha256:4cae512d121a8522d41e66d942fb06c526bc1fd32c2c181d5fe62fe65b671638"}, + {file = "xarray-2024.6.0-py3-none-any.whl", hash = "sha256:721a7394e8ec3d592b2d8ebe21eed074ac077dc1bb1bd777ce00e41700b4866c"}, + {file = "xarray-2024.6.0.tar.gz", hash = "sha256:0b91e0bc4dc0296947947640fe31ec6e867ce258d2f7cbc10bedf4a6d68340c7"}, ] [package.dependencies] @@ -1760,13 +1725,13 @@ viz = ["matplotlib", "nc-time-axis", "seaborn"] [[package]] name = "zipp" -version = "3.20.0" +version = "3.19.2" description = "Backport of pathlib-compatible object wrapper for zip files" optional = true python-versions = ">=3.8" files = [ - {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, - {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, + {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, + {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, ] [package.extras] From 4f4efbe0030fd10c37ee5ef759c5c20271e60bb4 Mon Sep 17 00:00:00 2001 From: Laura Sandoval Date: Tue, 27 Aug 2024 09:56:01 -0600 Subject: [PATCH 32/32] pr response --- imap_processing/spice/kernels.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/imap_processing/spice/kernels.py b/imap_processing/spice/kernels.py index 6830de06b..6f7ce1492 100644 --- a/imap_processing/spice/kernels.py +++ b/imap_processing/spice/kernels.py @@ -1,11 +1,12 @@ """Functions for furnishing and tracking SPICE kernels.""" -from contextlib import contextmanager import functools import logging import os +from collections.abc import Generator +from contextlib import contextmanager from pathlib import Path -from typing import Any, Callable, Optional, Generator +from typing import Any, Callable, Optional import numpy as np import spiceypy as spice @@ -342,7 +343,7 @@ def _average_quaternions(et_times: np.ndarray) -> NDArray: # Aggregate quaternions into a single matrix. aggregate += np.outer(body_quat, body_quat) - # Reference: "On Averaging Rotations" + # Reference: "On Averaging Rotations". # Link: https://link.springer.com/content/pdf/10.1023/A:1011129215388.pdf aggregate /= len(et_times)